aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c72
-rw-r--r--fs/namei.c13
-rw-r--r--fs/open.c2
3 files changed, 33 insertions, 54 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 41ae8e0de72d..895823d0149d 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -105,36 +105,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
105SYSCALL_DEFINE1(uselib, const char __user *, library) 105SYSCALL_DEFINE1(uselib, const char __user *, library)
106{ 106{
107 struct file *file; 107 struct file *file;
108 struct nameidata nd;
109 char *tmp = getname(library); 108 char *tmp = getname(library);
110 int error = PTR_ERR(tmp); 109 int error = PTR_ERR(tmp);
111 110
112 if (!IS_ERR(tmp)) { 111 if (IS_ERR(tmp))
113 error = path_lookup_open(AT_FDCWD, tmp, 112 goto out;
114 LOOKUP_FOLLOW, &nd, 113
115 FMODE_READ|FMODE_EXEC); 114 file = do_filp_open(AT_FDCWD, tmp,
116 putname(tmp); 115 O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
117 } 116 MAY_READ | MAY_EXEC | MAY_OPEN);
118 if (error) 117 putname(tmp);
118 error = PTR_ERR(file);
119 if (IS_ERR(file))
119 goto out; 120 goto out;
120 121
121 error = -EINVAL; 122 error = -EINVAL;
122 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 123 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
123 goto exit; 124 goto exit;
124 125
125 error = -EACCES; 126 error = -EACCES;
126 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 127 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
127 goto exit;
128
129 error = may_open(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN, 0);
130 if (error)
131 goto exit; 128 goto exit;
132 129
133 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
134 error = PTR_ERR(file);
135 if (IS_ERR(file))
136 goto out;
137
138 fsnotify_open(file->f_path.dentry); 130 fsnotify_open(file->f_path.dentry);
139 131
140 error = -ENOEXEC; 132 error = -ENOEXEC;
@@ -156,13 +148,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
156 } 148 }
157 read_unlock(&binfmt_lock); 149 read_unlock(&binfmt_lock);
158 } 150 }
151exit:
159 fput(file); 152 fput(file);
160out: 153out:
161 return error; 154 return error;
162exit:
163 release_open_intent(&nd);
164 path_put(&nd.path);
165 goto out;
166} 155}
167 156
168#ifdef CONFIG_MMU 157#ifdef CONFIG_MMU
@@ -657,44 +646,33 @@ EXPORT_SYMBOL(setup_arg_pages);
657 646
658struct file *open_exec(const char *name) 647struct file *open_exec(const char *name)
659{ 648{
660 struct nameidata nd;
661 struct file *file; 649 struct file *file;
662 int err; 650 int err;
663 651
664 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, 652 file = do_filp_open(AT_FDCWD, name,
665 FMODE_READ|FMODE_EXEC); 653 O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
666 if (err) 654 MAY_EXEC | MAY_OPEN);
655 if (IS_ERR(file))
667 goto out; 656 goto out;
668 657
669 err = -EACCES; 658 err = -EACCES;
670 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 659 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
671 goto out_path_put; 660 goto exit;
672
673 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
674 goto out_path_put;
675
676 err = may_open(&nd.path, MAY_EXEC | MAY_OPEN, 0);
677 if (err)
678 goto out_path_put;
679 661
680 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 662 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
681 if (IS_ERR(file)) 663 goto exit;
682 return file;
683 664
684 fsnotify_open(file->f_path.dentry); 665 fsnotify_open(file->f_path.dentry);
685 666
686 err = deny_write_access(file); 667 err = deny_write_access(file);
687 if (err) { 668 if (err)
688 fput(file); 669 goto exit;
689 goto out;
690 }
691 670
671out:
692 return file; 672 return file;
693 673
694 out_path_put: 674exit:
695 release_open_intent(&nd); 675 fput(file);
696 path_put(&nd.path);
697 out:
698 return ERR_PTR(err); 676 return ERR_PTR(err);
699} 677}
700EXPORT_SYMBOL(open_exec); 678EXPORT_SYMBOL(open_exec);
diff --git a/fs/namei.c b/fs/namei.c
index 78f253cd2d4f..967c3db92724 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1130,8 +1130,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1130 * @nd: pointer to nameidata 1130 * @nd: pointer to nameidata
1131 * @open_flags: open intent flags 1131 * @open_flags: open intent flags
1132 */ 1132 */
1133int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags, 1133static int path_lookup_open(int dfd, const char *name,
1134 struct nameidata *nd, int open_flags) 1134 unsigned int lookup_flags, struct nameidata *nd, int open_flags)
1135{ 1135{
1136 struct file *filp = get_empty_filp(); 1136 struct file *filp = get_empty_filp();
1137 int err; 1137 int err;
@@ -1637,18 +1637,19 @@ static int open_will_write_to_fs(int flag, struct inode *inode)
1637 * open_to_namei_flags() for more details. 1637 * open_to_namei_flags() for more details.
1638 */ 1638 */
1639struct file *do_filp_open(int dfd, const char *pathname, 1639struct file *do_filp_open(int dfd, const char *pathname,
1640 int open_flag, int mode) 1640 int open_flag, int mode, int acc_mode)
1641{ 1641{
1642 struct file *filp; 1642 struct file *filp;
1643 struct nameidata nd; 1643 struct nameidata nd;
1644 int acc_mode, error; 1644 int error;
1645 struct path path; 1645 struct path path;
1646 struct dentry *dir; 1646 struct dentry *dir;
1647 int count = 0; 1647 int count = 0;
1648 int will_write; 1648 int will_write;
1649 int flag = open_to_namei_flags(open_flag); 1649 int flag = open_to_namei_flags(open_flag);
1650 1650
1651 acc_mode = MAY_OPEN | ACC_MODE(flag); 1651 if (!acc_mode)
1652 acc_mode = MAY_OPEN | ACC_MODE(flag);
1652 1653
1653 /* O_TRUNC implies we need access checks for write permissions */ 1654 /* O_TRUNC implies we need access checks for write permissions */
1654 if (flag & O_TRUNC) 1655 if (flag & O_TRUNC)
@@ -1869,7 +1870,7 @@ do_link:
1869 */ 1870 */
1870struct file *filp_open(const char *filename, int flags, int mode) 1871struct file *filp_open(const char *filename, int flags, int mode)
1871{ 1872{
1872 return do_filp_open(AT_FDCWD, filename, flags, mode); 1873 return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
1873} 1874}
1874EXPORT_SYMBOL(filp_open); 1875EXPORT_SYMBOL(filp_open);
1875 1876
diff --git a/fs/open.c b/fs/open.c
index 377eb25b6abf..bdfbf03615a4 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1033,7 +1033,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
1033 if (!IS_ERR(tmp)) { 1033 if (!IS_ERR(tmp)) {
1034 fd = get_unused_fd_flags(flags); 1034 fd = get_unused_fd_flags(flags);
1035 if (fd >= 0) { 1035 if (fd >= 0) {
1036 struct file *f = do_filp_open(dfd, tmp, flags, mode); 1036 struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);
1037 if (IS_ERR(f)) { 1037 if (IS_ERR(f)) {
1038 put_unused_fd(fd); 1038 put_unused_fd(fd);
1039 fd = PTR_ERR(f); 1039 fd = PTR_ERR(f);