Loading fs/exec.c +6 −4 Original line number Diff line number Diff line Loading @@ -110,13 +110,14 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) static const struct open_flags uselib_flags = { .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, .acc_mode = MAY_READ | MAY_EXEC | MAY_OPEN, .intent = LOOKUP_OPEN .intent = LOOKUP_OPEN, .lookup_flags = LOOKUP_FOLLOW, }; if (IS_ERR(tmp)) goto out; file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW); file = do_filp_open(AT_FDCWD, tmp, &uselib_flags); putname(tmp); error = PTR_ERR(file); if (IS_ERR(file)) Loading Loading @@ -756,10 +757,11 @@ struct file *open_exec(const char *name) static const struct open_flags open_exec_flags = { .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, .acc_mode = MAY_EXEC | MAY_OPEN, .intent = LOOKUP_OPEN .intent = LOOKUP_OPEN, .lookup_flags = LOOKUP_FOLLOW, }; file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW); file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags); if (IS_ERR(file)) goto out; Loading fs/internal.h +3 −2 Original line number Diff line number Diff line Loading @@ -96,11 +96,12 @@ struct open_flags { umode_t mode; int acc_mode; int intent; int lookup_flags; }; extern struct file *do_filp_open(int dfd, struct filename *pathname, const struct open_flags *op, int flags); const struct open_flags *op); extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, const char *, const struct open_flags *, int lookup_flags); const char *, const struct open_flags *); extern long do_handle_open(int mountdirfd, struct file_handle __user *ufh, int open_flag); Loading fs/namei.c +4 −4 Original line number Diff line number Diff line Loading @@ -2969,9 +2969,10 @@ static struct file *path_openat(int dfd, struct filename *pathname, } struct file *do_filp_open(int dfd, struct filename *pathname, const struct open_flags *op, int flags) const struct open_flags *op) { struct nameidata nd; int flags = op->lookup_flags; struct file *filp; filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU); Loading @@ -2983,17 +2984,16 @@ struct file *do_filp_open(int dfd, struct filename *pathname, } struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, const char *name, const struct open_flags *op, int flags) const char *name, const struct open_flags *op) { struct nameidata nd; struct file *file; struct filename filename = { .name = name }; int flags = op->lookup_flags | LOOKUP_ROOT; nd.root.mnt = mnt; nd.root.dentry = dentry; flags |= LOOKUP_ROOT; if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) return ERR_PTR(-ELOOP); Loading fs/open.c +28 −21 Original line number Diff line number Diff line Loading @@ -876,7 +876,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o lookup_flags |= LOOKUP_DIRECTORY; if (!(flags & O_NOFOLLOW)) lookup_flags |= LOOKUP_FOLLOW; return lookup_flags; op->lookup_flags = lookup_flags; return 0; } /** Loading @@ -893,8 +894,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o struct file *file_open_name(struct filename *name, int flags, umode_t mode) { struct open_flags op; int lookup = build_open_flags(flags, mode, &op); return do_filp_open(AT_FDCWD, name, &op, lookup); int err = build_open_flags(flags, mode, &op); return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op); } /** Loading @@ -919,27 +920,34 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, const char *filename, int flags) { struct open_flags op; int lookup = build_open_flags(flags, 0, &op); int err = build_open_flags(flags, 0, &op); if (err) return ERR_PTR(err); if (flags & O_CREAT) return ERR_PTR(-EINVAL); if (!filename && (flags & O_DIRECTORY)) if (!dentry->d_inode->i_op->lookup) return ERR_PTR(-ENOTDIR); return do_file_open_root(dentry, mnt, filename, &op, lookup); return do_file_open_root(dentry, mnt, filename, &op); } EXPORT_SYMBOL(file_open_root); long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; int lookup = build_open_flags(flags, mode, &op); struct filename *tmp = getname(filename); int fd = PTR_ERR(tmp); int fd = build_open_flags(flags, mode, &op); struct filename *tmp; if (fd) return fd; tmp = getname(filename); if (IS_ERR(tmp)) return PTR_ERR(tmp); if (!IS_ERR(tmp)) { fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, &op, lookup); struct file *f = do_filp_open(dfd, tmp, &op); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); Loading @@ -949,7 +957,6 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) } } putname(tmp); } return fd; } Loading Loading
fs/exec.c +6 −4 Original line number Diff line number Diff line Loading @@ -110,13 +110,14 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) static const struct open_flags uselib_flags = { .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, .acc_mode = MAY_READ | MAY_EXEC | MAY_OPEN, .intent = LOOKUP_OPEN .intent = LOOKUP_OPEN, .lookup_flags = LOOKUP_FOLLOW, }; if (IS_ERR(tmp)) goto out; file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW); file = do_filp_open(AT_FDCWD, tmp, &uselib_flags); putname(tmp); error = PTR_ERR(file); if (IS_ERR(file)) Loading Loading @@ -756,10 +757,11 @@ struct file *open_exec(const char *name) static const struct open_flags open_exec_flags = { .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, .acc_mode = MAY_EXEC | MAY_OPEN, .intent = LOOKUP_OPEN .intent = LOOKUP_OPEN, .lookup_flags = LOOKUP_FOLLOW, }; file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW); file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags); if (IS_ERR(file)) goto out; Loading
fs/internal.h +3 −2 Original line number Diff line number Diff line Loading @@ -96,11 +96,12 @@ struct open_flags { umode_t mode; int acc_mode; int intent; int lookup_flags; }; extern struct file *do_filp_open(int dfd, struct filename *pathname, const struct open_flags *op, int flags); const struct open_flags *op); extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, const char *, const struct open_flags *, int lookup_flags); const char *, const struct open_flags *); extern long do_handle_open(int mountdirfd, struct file_handle __user *ufh, int open_flag); Loading
fs/namei.c +4 −4 Original line number Diff line number Diff line Loading @@ -2969,9 +2969,10 @@ static struct file *path_openat(int dfd, struct filename *pathname, } struct file *do_filp_open(int dfd, struct filename *pathname, const struct open_flags *op, int flags) const struct open_flags *op) { struct nameidata nd; int flags = op->lookup_flags; struct file *filp; filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU); Loading @@ -2983,17 +2984,16 @@ struct file *do_filp_open(int dfd, struct filename *pathname, } struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, const char *name, const struct open_flags *op, int flags) const char *name, const struct open_flags *op) { struct nameidata nd; struct file *file; struct filename filename = { .name = name }; int flags = op->lookup_flags | LOOKUP_ROOT; nd.root.mnt = mnt; nd.root.dentry = dentry; flags |= LOOKUP_ROOT; if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) return ERR_PTR(-ELOOP); Loading
fs/open.c +28 −21 Original line number Diff line number Diff line Loading @@ -876,7 +876,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o lookup_flags |= LOOKUP_DIRECTORY; if (!(flags & O_NOFOLLOW)) lookup_flags |= LOOKUP_FOLLOW; return lookup_flags; op->lookup_flags = lookup_flags; return 0; } /** Loading @@ -893,8 +894,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o struct file *file_open_name(struct filename *name, int flags, umode_t mode) { struct open_flags op; int lookup = build_open_flags(flags, mode, &op); return do_filp_open(AT_FDCWD, name, &op, lookup); int err = build_open_flags(flags, mode, &op); return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op); } /** Loading @@ -919,27 +920,34 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, const char *filename, int flags) { struct open_flags op; int lookup = build_open_flags(flags, 0, &op); int err = build_open_flags(flags, 0, &op); if (err) return ERR_PTR(err); if (flags & O_CREAT) return ERR_PTR(-EINVAL); if (!filename && (flags & O_DIRECTORY)) if (!dentry->d_inode->i_op->lookup) return ERR_PTR(-ENOTDIR); return do_file_open_root(dentry, mnt, filename, &op, lookup); return do_file_open_root(dentry, mnt, filename, &op); } EXPORT_SYMBOL(file_open_root); long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; int lookup = build_open_flags(flags, mode, &op); struct filename *tmp = getname(filename); int fd = PTR_ERR(tmp); int fd = build_open_flags(flags, mode, &op); struct filename *tmp; if (fd) return fd; tmp = getname(filename); if (IS_ERR(tmp)) return PTR_ERR(tmp); if (!IS_ERR(tmp)) { fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, &op, lookup); struct file *f = do_filp_open(dfd, tmp, &op); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); Loading @@ -949,7 +957,6 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) } } putname(tmp); } return fd; } Loading