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