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>
This commit is contained in:
Родитель
a44ddbb6d8
Коммит
6e8341a11e
76
fs/exec.c
76
fs/exec.c
|
@ -105,36 +105,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
|
|||
SYSCALL_DEFINE1(uselib, const char __user *, library)
|
||||
{
|
||||
struct file *file;
|
||||
struct nameidata nd;
|
||||
char *tmp = getname(library);
|
||||
int error = PTR_ERR(tmp);
|
||||
|
||||
if (!IS_ERR(tmp)) {
|
||||
error = path_lookup_open(AT_FDCWD, tmp,
|
||||
LOOKUP_FOLLOW, &nd,
|
||||
FMODE_READ|FMODE_EXEC);
|
||||
putname(tmp);
|
||||
}
|
||||
if (error)
|
||||
if (IS_ERR(tmp))
|
||||
goto out;
|
||||
|
||||
error = -EINVAL;
|
||||
if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
|
||||
goto exit;
|
||||
|
||||
error = -EACCES;
|
||||
if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
|
||||
goto exit;
|
||||
|
||||
error = may_open(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN, 0);
|
||||
if (error)
|
||||
goto exit;
|
||||
|
||||
file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
|
||||
file = do_filp_open(AT_FDCWD, tmp,
|
||||
O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
|
||||
MAY_READ | MAY_EXEC | MAY_OPEN);
|
||||
putname(tmp);
|
||||
error = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out;
|
||||
|
||||
error = -EINVAL;
|
||||
if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
|
||||
goto exit;
|
||||
|
||||
error = -EACCES;
|
||||
if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
|
||||
goto exit;
|
||||
|
||||
fsnotify_open(file->f_path.dentry);
|
||||
|
||||
error = -ENOEXEC;
|
||||
|
@ -156,13 +148,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
|
|||
}
|
||||
read_unlock(&binfmt_lock);
|
||||
}
|
||||
exit:
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
exit:
|
||||
release_open_intent(&nd);
|
||||
path_put(&nd.path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
@ -657,44 +646,33 @@ EXPORT_SYMBOL(setup_arg_pages);
|
|||
|
||||
struct file *open_exec(const char *name)
|
||||
{
|
||||
struct nameidata nd;
|
||||
struct file *file;
|
||||
int err;
|
||||
|
||||
err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd,
|
||||
FMODE_READ|FMODE_EXEC);
|
||||
if (err)
|
||||
file = do_filp_open(AT_FDCWD, name,
|
||||
O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
|
||||
MAY_EXEC | MAY_OPEN);
|
||||
if (IS_ERR(file))
|
||||
goto out;
|
||||
|
||||
err = -EACCES;
|
||||
if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
|
||||
goto out_path_put;
|
||||
if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
|
||||
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 (IS_ERR(file))
|
||||
return file;
|
||||
if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
|
||||
goto exit;
|
||||
|
||||
fsnotify_open(file->f_path.dentry);
|
||||
|
||||
err = deny_write_access(file);
|
||||
if (err) {
|
||||
fput(file);
|
||||
goto out;
|
||||
}
|
||||
if (err)
|
||||
goto exit;
|
||||
|
||||
out:
|
||||
return file;
|
||||
|
||||
out_path_put:
|
||||
release_open_intent(&nd);
|
||||
path_put(&nd.path);
|
||||
out:
|
||||
exit:
|
||||
fput(file);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
EXPORT_SYMBOL(open_exec);
|
||||
|
|
11
fs/namei.c
11
fs/namei.c
|
@ -1130,8 +1130,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
|
|||
* @nd: pointer to nameidata
|
||||
* @open_flags: open intent flags
|
||||
*/
|
||||
int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
|
||||
struct nameidata *nd, int open_flags)
|
||||
static int path_lookup_open(int dfd, const char *name,
|
||||
unsigned int lookup_flags, struct nameidata *nd, int open_flags)
|
||||
{
|
||||
struct file *filp = get_empty_filp();
|
||||
int err;
|
||||
|
@ -1637,17 +1637,18 @@ static int open_will_write_to_fs(int flag, struct inode *inode)
|
|||
* open_to_namei_flags() for more details.
|
||||
*/
|
||||
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 nameidata nd;
|
||||
int acc_mode, error;
|
||||
int error;
|
||||
struct path path;
|
||||
struct dentry *dir;
|
||||
int count = 0;
|
||||
int will_write;
|
||||
int flag = open_to_namei_flags(open_flag);
|
||||
|
||||
if (!acc_mode)
|
||||
acc_mode = MAY_OPEN | ACC_MODE(flag);
|
||||
|
||||
/* O_TRUNC implies we need access checks for write permissions */
|
||||
|
@ -1869,7 +1870,7 @@ do_link:
|
|||
*/
|
||||
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);
|
||||
|
||||
|
|
|
@ -1033,7 +1033,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
|
|||
if (!IS_ERR(tmp)) {
|
||||
fd = get_unused_fd_flags(flags);
|
||||
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)) {
|
||||
put_unused_fd(fd);
|
||||
fd = PTR_ERR(f);
|
||||
|
|
|
@ -2118,7 +2118,7 @@ extern struct file *create_write_pipe(int flags);
|
|||
extern void free_write_pipe(struct file *);
|
||||
|
||||
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 kernel_read(struct file *, unsigned long, char *, unsigned long);
|
||||
|
|
|
@ -69,7 +69,6 @@ extern int path_lookup(const char *, unsigned, struct nameidata *);
|
|||
extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
|
||||
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,
|
||||
int (*open)(struct inode *, struct file *));
|
||||
extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
|
||||
|
|
Загрузка…
Ссылка в новой задаче