Commit 6e8341a11eb21826b7192d0bb88cb5b44900a9af
1 parent
a44ddbb6d8
Exists in
master
and in
4 other branches
Switch open_exec() and sys_uselib() to do_open_filp()
... and make path_lookup_open() static Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 5 changed files with 34 additions and 56 deletions Side-by-side Diff
fs/exec.c
... | ... | @@ -105,36 +105,28 @@ |
105 | 105 | SYSCALL_DEFINE1(uselib, const char __user *, library) |
106 | 106 | { |
107 | 107 | struct file *file; |
108 | - struct nameidata nd; | |
109 | 108 | char *tmp = getname(library); |
110 | 109 | int error = PTR_ERR(tmp); |
111 | 110 | |
112 | - if (!IS_ERR(tmp)) { | |
113 | - error = path_lookup_open(AT_FDCWD, tmp, | |
114 | - LOOKUP_FOLLOW, &nd, | |
115 | - FMODE_READ|FMODE_EXEC); | |
116 | - putname(tmp); | |
117 | - } | |
118 | - if (error) | |
111 | + if (IS_ERR(tmp)) | |
119 | 112 | goto out; |
120 | 113 | |
114 | + file = do_filp_open(AT_FDCWD, tmp, | |
115 | + O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, | |
116 | + MAY_READ | MAY_EXEC | MAY_OPEN); | |
117 | + putname(tmp); | |
118 | + error = PTR_ERR(file); | |
119 | + if (IS_ERR(file)) | |
120 | + goto out; | |
121 | + | |
121 | 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 | 124 | goto exit; |
124 | 125 | |
125 | 126 | error = -EACCES; |
126 | - if (nd.path.mnt->mnt_flags & MNT_NOEXEC) | |
127 | + if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) | |
127 | 128 | goto exit; |
128 | 129 | |
129 | - error = may_open(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN, 0); | |
130 | - if (error) | |
131 | - goto exit; | |
132 | - | |
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 | 130 | fsnotify_open(file->f_path.dentry); |
139 | 131 | |
140 | 132 | error = -ENOEXEC; |
141 | 133 | |
... | ... | @@ -156,13 +148,10 @@ |
156 | 148 | } |
157 | 149 | read_unlock(&binfmt_lock); |
158 | 150 | } |
151 | +exit: | |
159 | 152 | fput(file); |
160 | 153 | out: |
161 | 154 | return error; |
162 | -exit: | |
163 | - release_open_intent(&nd); | |
164 | - path_put(&nd.path); | |
165 | - goto out; | |
166 | 155 | } |
167 | 156 | |
168 | 157 | #ifdef CONFIG_MMU |
169 | 158 | |
170 | 159 | |
171 | 160 | |
172 | 161 | |
173 | 162 | |
174 | 163 | |
175 | 164 | |
... | ... | @@ -657,44 +646,33 @@ |
657 | 646 | |
658 | 647 | struct file *open_exec(const char *name) |
659 | 648 | { |
660 | - struct nameidata nd; | |
661 | 649 | struct file *file; |
662 | 650 | int err; |
663 | 651 | |
664 | - err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, | |
665 | - FMODE_READ|FMODE_EXEC); | |
666 | - if (err) | |
652 | + file = do_filp_open(AT_FDCWD, name, | |
653 | + O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, | |
654 | + MAY_EXEC | MAY_OPEN); | |
655 | + if (IS_ERR(file)) | |
667 | 656 | goto out; |
668 | 657 | |
669 | 658 | err = -EACCES; |
670 | - if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) | |
671 | - goto out_path_put; | |
659 | + if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) | |
660 | + goto exit; | |
672 | 661 | |
673 | - if (nd.path.mnt->mnt_flags & MNT_NOEXEC) | |
674 | - goto out_path_put; | |
662 | + if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) | |
663 | + goto exit; | |
675 | 664 | |
676 | - err = may_open(&nd.path, MAY_EXEC | MAY_OPEN, 0); | |
677 | - if (err) | |
678 | - goto out_path_put; | |
679 | - | |
680 | - file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); | |
681 | - if (IS_ERR(file)) | |
682 | - return file; | |
683 | - | |
684 | 665 | fsnotify_open(file->f_path.dentry); |
685 | 666 | |
686 | 667 | err = deny_write_access(file); |
687 | - if (err) { | |
688 | - fput(file); | |
689 | - goto out; | |
690 | - } | |
668 | + if (err) | |
669 | + goto exit; | |
691 | 670 | |
671 | +out: | |
692 | 672 | return file; |
693 | 673 | |
694 | - out_path_put: | |
695 | - release_open_intent(&nd); | |
696 | - path_put(&nd.path); | |
697 | - out: | |
674 | +exit: | |
675 | + fput(file); | |
698 | 676 | return ERR_PTR(err); |
699 | 677 | } |
700 | 678 | EXPORT_SYMBOL(open_exec); |
fs/namei.c
... | ... | @@ -1130,8 +1130,8 @@ |
1130 | 1130 | * @nd: pointer to nameidata |
1131 | 1131 | * @open_flags: open intent flags |
1132 | 1132 | */ |
1133 | -int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags, | |
1134 | - struct nameidata *nd, int open_flags) | |
1133 | +static int path_lookup_open(int dfd, const char *name, | |
1134 | + unsigned int lookup_flags, struct nameidata *nd, int open_flags) | |
1135 | 1135 | { |
1136 | 1136 | struct file *filp = get_empty_filp(); |
1137 | 1137 | int err; |
1138 | 1138 | |
1139 | 1139 | |
... | ... | @@ -1637,18 +1637,19 @@ |
1637 | 1637 | * open_to_namei_flags() for more details. |
1638 | 1638 | */ |
1639 | 1639 | struct 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 | 1642 | struct file *filp; |
1643 | 1643 | struct nameidata nd; |
1644 | - int acc_mode, error; | |
1644 | + int error; | |
1645 | 1645 | struct path path; |
1646 | 1646 | struct dentry *dir; |
1647 | 1647 | int count = 0; |
1648 | 1648 | int will_write; |
1649 | 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 | 1654 | /* O_TRUNC implies we need access checks for write permissions */ |
1654 | 1655 | if (flag & O_TRUNC) |
... | ... | @@ -1869,7 +1870,7 @@ |
1869 | 1870 | */ |
1870 | 1871 | struct 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 | } |
1874 | 1875 | EXPORT_SYMBOL(filp_open); |
1875 | 1876 |
fs/open.c
... | ... | @@ -1033,7 +1033,7 @@ |
1033 | 1033 | if (!IS_ERR(tmp)) { |
1034 | 1034 | fd = get_unused_fd_flags(flags); |
1035 | 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 | 1037 | if (IS_ERR(f)) { |
1038 | 1038 | put_unused_fd(fd); |
1039 | 1039 | fd = PTR_ERR(f); |
include/linux/fs.h
... | ... | @@ -2118,7 +2118,7 @@ |
2118 | 2118 | extern void free_write_pipe(struct file *); |
2119 | 2119 | |
2120 | 2120 | extern struct file *do_filp_open(int dfd, const char *pathname, |
2121 | - int open_flag, int mode); | |
2121 | + int open_flag, int mode, int acc_mode); | |
2122 | 2122 | extern int may_open(struct path *, int, int); |
2123 | 2123 | |
2124 | 2124 | extern int kernel_read(struct file *, unsigned long, char *, unsigned long); |
include/linux/namei.h
... | ... | @@ -69,7 +69,6 @@ |
69 | 69 | extern int vfs_path_lookup(struct dentry *, struct vfsmount *, |
70 | 70 | const char *, unsigned int, struct nameidata *); |
71 | 71 | |
72 | -extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags); | |
73 | 72 | extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, |
74 | 73 | int (*open)(struct inode *, struct file *)); |
75 | 74 | extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); |