aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c86
1 files changed, 29 insertions, 57 deletions
diff --git a/fs/exec.c b/fs/exec.c
index a3a8ce83940f..895823d0149d 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -69,17 +69,18 @@ int suid_dumpable = 0;
69static LIST_HEAD(formats); 69static LIST_HEAD(formats);
70static DEFINE_RWLOCK(binfmt_lock); 70static DEFINE_RWLOCK(binfmt_lock);
71 71
72int register_binfmt(struct linux_binfmt * fmt) 72int __register_binfmt(struct linux_binfmt * fmt, int insert)
73{ 73{
74 if (!fmt) 74 if (!fmt)
75 return -EINVAL; 75 return -EINVAL;
76 write_lock(&binfmt_lock); 76 write_lock(&binfmt_lock);
77 list_add(&fmt->lh, &formats); 77 insert ? list_add(&fmt->lh, &formats) :
78 list_add_tail(&fmt->lh, &formats);
78 write_unlock(&binfmt_lock); 79 write_unlock(&binfmt_lock);
79 return 0; 80 return 0;
80} 81}
81 82
82EXPORT_SYMBOL(register_binfmt); 83EXPORT_SYMBOL(__register_binfmt);
83 84
84void unregister_binfmt(struct linux_binfmt * fmt) 85void unregister_binfmt(struct linux_binfmt * fmt)
85{ 86{
@@ -104,40 +105,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
104SYSCALL_DEFINE1(uselib, const char __user *, library) 105SYSCALL_DEFINE1(uselib, const char __user *, library)
105{ 106{
106 struct file *file; 107 struct file *file;
107 struct nameidata nd;
108 char *tmp = getname(library); 108 char *tmp = getname(library);
109 int error = PTR_ERR(tmp); 109 int error = PTR_ERR(tmp);
110 110
111 if (!IS_ERR(tmp)) { 111 if (IS_ERR(tmp))
112 error = path_lookup_open(AT_FDCWD, tmp, 112 goto out;
113 LOOKUP_FOLLOW, &nd, 113
114 FMODE_READ|FMODE_EXEC); 114 file = do_filp_open(AT_FDCWD, tmp,
115 putname(tmp); 115 O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
116 } 116 MAY_READ | MAY_EXEC | MAY_OPEN);
117 if (error) 117 putname(tmp);
118 error = PTR_ERR(file);
119 if (IS_ERR(file))
118 goto out; 120 goto out;
119 121
120 error = -EINVAL; 122 error = -EINVAL;
121 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 123 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
122 goto exit; 124 goto exit;
123 125
124 error = -EACCES; 126 error = -EACCES;
125 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 127 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
126 goto exit;
127
128 error = inode_permission(nd.path.dentry->d_inode,
129 MAY_READ | MAY_EXEC | MAY_OPEN);
130 if (error)
131 goto exit;
132 error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
133 if (error)
134 goto exit; 128 goto exit;
135 129
136 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
137 error = PTR_ERR(file);
138 if (IS_ERR(file))
139 goto out;
140
141 fsnotify_open(file->f_path.dentry); 130 fsnotify_open(file->f_path.dentry);
142 131
143 error = -ENOEXEC; 132 error = -ENOEXEC;
@@ -159,13 +148,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
159 } 148 }
160 read_unlock(&binfmt_lock); 149 read_unlock(&binfmt_lock);
161 } 150 }
151exit:
162 fput(file); 152 fput(file);
163out: 153out:
164 return error; 154 return error;
165exit:
166 release_open_intent(&nd);
167 path_put(&nd.path);
168 goto out;
169} 155}
170 156
171#ifdef CONFIG_MMU 157#ifdef CONFIG_MMU
@@ -660,47 +646,33 @@ EXPORT_SYMBOL(setup_arg_pages);
660 646
661struct file *open_exec(const char *name) 647struct file *open_exec(const char *name)
662{ 648{
663 struct nameidata nd;
664 struct file *file; 649 struct file *file;
665 int err; 650 int err;
666 651
667 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, 652 file = do_filp_open(AT_FDCWD, name,
668 FMODE_READ|FMODE_EXEC); 653 O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
669 if (err) 654 MAY_EXEC | MAY_OPEN);
655 if (IS_ERR(file))
670 goto out; 656 goto out;
671 657
672 err = -EACCES; 658 err = -EACCES;
673 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 659 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
674 goto out_path_put; 660 goto exit;
675
676 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
677 goto out_path_put;
678
679 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
680 if (err)
681 goto out_path_put;
682 err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
683 if (err)
684 goto out_path_put;
685 661
686 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 662 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
687 if (IS_ERR(file)) 663 goto exit;
688 return file;
689 664
690 fsnotify_open(file->f_path.dentry); 665 fsnotify_open(file->f_path.dentry);
691 666
692 err = deny_write_access(file); 667 err = deny_write_access(file);
693 if (err) { 668 if (err)
694 fput(file); 669 goto exit;
695 goto out;
696 }
697 670
671out:
698 return file; 672 return file;
699 673
700 out_path_put: 674exit:
701 release_open_intent(&nd); 675 fput(file);
702 path_put(&nd.path);
703 out:
704 return ERR_PTR(err); 676 return ERR_PTR(err);
705} 677}
706EXPORT_SYMBOL(open_exec); 678EXPORT_SYMBOL(open_exec);