Commit 6e8341a1 authored by Al Viro's avatar Al Viro

Switch open_exec() and sys_uselib() to do_open_filp()

... and make path_lookup_open() static
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a44ddbb6
...@@ -105,36 +105,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt) ...@@ -105,36 +105,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
SYSCALL_DEFINE1(uselib, const char __user *, library) SYSCALL_DEFINE1(uselib, const char __user *, library)
{ {
struct file *file; struct file *file;
struct nameidata nd;
char *tmp = getname(library); char *tmp = getname(library);
int error = PTR_ERR(tmp); int error = PTR_ERR(tmp);
if (!IS_ERR(tmp)) { if (IS_ERR(tmp))
error = path_lookup_open(AT_FDCWD, tmp, goto out;
LOOKUP_FOLLOW, &nd,
FMODE_READ|FMODE_EXEC); file = do_filp_open(AT_FDCWD, tmp,
O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
MAY_READ | MAY_EXEC | MAY_OPEN);
putname(tmp); putname(tmp);
} error = PTR_ERR(file);
if (error) if (IS_ERR(file))
goto out; goto out;
error = -EINVAL; error = -EINVAL;
if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
goto exit; goto exit;
error = -EACCES; error = -EACCES;
if (nd.path.mnt->mnt_flags & MNT_NOEXEC) if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
goto exit;
error = may_open(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN, 0);
if (error)
goto exit; goto exit;
file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
error = PTR_ERR(file);
if (IS_ERR(file))
goto out;
fsnotify_open(file->f_path.dentry); fsnotify_open(file->f_path.dentry);
error = -ENOEXEC; error = -ENOEXEC;
...@@ -156,13 +148,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) ...@@ -156,13 +148,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
} }
read_unlock(&binfmt_lock); read_unlock(&binfmt_lock);
} }
exit:
fput(file); fput(file);
out: out:
return error; return error;
exit:
release_open_intent(&nd);
path_put(&nd.path);
goto out;
} }
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
...@@ -657,44 +646,33 @@ EXPORT_SYMBOL(setup_arg_pages); ...@@ -657,44 +646,33 @@ EXPORT_SYMBOL(setup_arg_pages);
struct file *open_exec(const char *name) struct file *open_exec(const char *name)
{ {
struct nameidata nd;
struct file *file; struct file *file;
int err; int err;
err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, file = do_filp_open(AT_FDCWD, name,
FMODE_READ|FMODE_EXEC); O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
if (err) MAY_EXEC | MAY_OPEN);
if (IS_ERR(file))
goto out; goto out;
err = -EACCES; err = -EACCES;
if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
goto out_path_put; goto exit;
if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
goto out_path_put;
err = may_open(&nd.path, MAY_EXEC | MAY_OPEN, 0);
if (err)
goto out_path_put;
file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
if (IS_ERR(file)) goto exit;
return file;
fsnotify_open(file->f_path.dentry); fsnotify_open(file->f_path.dentry);
err = deny_write_access(file); err = deny_write_access(file);
if (err) { if (err)
fput(file); goto exit;
goto out;
}
out:
return file; return file;
out_path_put: exit:
release_open_intent(&nd); fput(file);
path_put(&nd.path);
out:
return ERR_PTR(err); return ERR_PTR(err);
} }
EXPORT_SYMBOL(open_exec); EXPORT_SYMBOL(open_exec);
......
...@@ -1130,8 +1130,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, ...@@ -1130,8 +1130,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
* @nd: pointer to nameidata * @nd: pointer to nameidata
* @open_flags: open intent flags * @open_flags: open intent flags
*/ */
int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags, static int path_lookup_open(int dfd, const char *name,
struct nameidata *nd, int open_flags) unsigned int lookup_flags, struct nameidata *nd, int open_flags)
{ {
struct file *filp = get_empty_filp(); struct file *filp = get_empty_filp();
int err; int err;
...@@ -1637,17 +1637,18 @@ static int open_will_write_to_fs(int flag, struct inode *inode) ...@@ -1637,17 +1637,18 @@ static int open_will_write_to_fs(int flag, struct inode *inode)
* open_to_namei_flags() for more details. * open_to_namei_flags() for more details.
*/ */
struct file *do_filp_open(int dfd, const char *pathname, struct file *do_filp_open(int dfd, const char *pathname,
int open_flag, int mode) int open_flag, int mode, int acc_mode)
{ {
struct file *filp; struct file *filp;
struct nameidata nd; struct nameidata nd;
int acc_mode, error; int error;
struct path path; struct path path;
struct dentry *dir; struct dentry *dir;
int count = 0; int count = 0;
int will_write; int will_write;
int flag = open_to_namei_flags(open_flag); int flag = open_to_namei_flags(open_flag);
if (!acc_mode)
acc_mode = MAY_OPEN | ACC_MODE(flag); acc_mode = MAY_OPEN | ACC_MODE(flag);
/* O_TRUNC implies we need access checks for write permissions */ /* O_TRUNC implies we need access checks for write permissions */
...@@ -1869,7 +1870,7 @@ struct file *do_filp_open(int dfd, const char *pathname, ...@@ -1869,7 +1870,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
*/ */
struct file *filp_open(const char *filename, int flags, int mode) struct file *filp_open(const char *filename, int flags, int mode)
{ {
return do_filp_open(AT_FDCWD, filename, flags, mode); return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
} }
EXPORT_SYMBOL(filp_open); EXPORT_SYMBOL(filp_open);
......
...@@ -1033,7 +1033,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode) ...@@ -1033,7 +1033,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
if (!IS_ERR(tmp)) { if (!IS_ERR(tmp)) {
fd = get_unused_fd_flags(flags); fd = get_unused_fd_flags(flags);
if (fd >= 0) { if (fd >= 0) {
struct file *f = do_filp_open(dfd, tmp, flags, mode); struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);
if (IS_ERR(f)) { if (IS_ERR(f)) {
put_unused_fd(fd); put_unused_fd(fd);
fd = PTR_ERR(f); fd = PTR_ERR(f);
......
...@@ -2118,7 +2118,7 @@ extern struct file *create_write_pipe(int flags); ...@@ -2118,7 +2118,7 @@ extern struct file *create_write_pipe(int flags);
extern void free_write_pipe(struct file *); extern void free_write_pipe(struct file *);
extern struct file *do_filp_open(int dfd, const char *pathname, extern struct file *do_filp_open(int dfd, const char *pathname,
int open_flag, int mode); int open_flag, int mode, int acc_mode);
extern int may_open(struct path *, int, int); extern int may_open(struct path *, int, int);
extern int kernel_read(struct file *, unsigned long, char *, unsigned long); extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
......
...@@ -69,7 +69,6 @@ extern int path_lookup(const char *, unsigned, struct nameidata *); ...@@ -69,7 +69,6 @@ extern int path_lookup(const char *, unsigned, struct nameidata *);
extern int vfs_path_lookup(struct dentry *, struct vfsmount *, extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
const char *, unsigned int, struct nameidata *); const char *, unsigned int, struct nameidata *);
extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
int (*open)(struct inode *, struct file *)); int (*open)(struct inode *, struct file *));
extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment