Loading fs/exec.c +25 −47 Original line number Diff line number Diff line Loading @@ -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); if (IS_ERR(tmp)) goto out; file = do_filp_open(AT_FDCWD, tmp, O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, MAY_READ | MAY_EXEC | MAY_OPEN); putname(tmp); } if (error) error = PTR_ERR(file); if (IS_ERR(file)) goto out; 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; 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) if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) 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); error = -ENOEXEC; Loading @@ -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 Loading Loading @@ -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 (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; if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) goto exit; 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); Loading fs/namei.c +7 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */ Loading Loading @@ -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) { return do_filp_open(AT_FDCWD, filename, flags, mode); return do_filp_open(AT_FDCWD, filename, flags, mode, 0); } EXPORT_SYMBOL(filp_open); Loading fs/open.c +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading include/linux/fs.h +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading include/linux/namei.h +0 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
fs/exec.c +25 −47 Original line number Diff line number Diff line Loading @@ -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); if (IS_ERR(tmp)) goto out; file = do_filp_open(AT_FDCWD, tmp, O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, MAY_READ | MAY_EXEC | MAY_OPEN); putname(tmp); } if (error) error = PTR_ERR(file); if (IS_ERR(file)) goto out; 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; 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) if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) 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); error = -ENOEXEC; Loading @@ -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 Loading Loading @@ -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 (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; if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) goto exit; 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); Loading
fs/namei.c +7 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */ Loading Loading @@ -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) { return do_filp_open(AT_FDCWD, filename, flags, mode); return do_filp_open(AT_FDCWD, filename, flags, mode, 0); } EXPORT_SYMBOL(filp_open); Loading
fs/open.c +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
include/linux/fs.h +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
include/linux/namei.h +0 −1 Original line number Diff line number Diff line Loading @@ -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); Loading