fdget_raw() users: switch to CLASS(fd_raw)

Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2024-05-31 22:45:26 -04:00
parent a6f46579d7
commit 048181992c
8 changed files with 47 additions and 83 deletions

View File

@ -235,12 +235,12 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
struct fd f = fdget_raw(fd); CLASS(fd_raw, f)(fd);
struct flock64 flock; struct flock64 flock;
long err = -EBADF; long err;
if (!fd_file(f)) if (fd_empty(f))
goto out; return -EBADF;
switch (cmd) { switch (cmd) {
case F_GETLK64: case F_GETLK64:
@ -271,8 +271,6 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
err = sys_fcntl64(fd, cmd, arg); err = sys_fcntl64(fd, cmd, arg);
break; break;
} }
fdput(f);
out:
return err; return err;
} }

View File

@ -570,24 +570,21 @@ static int check_fcntl_cmd(unsigned cmd)
SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
{ {
struct fd f = fdget_raw(fd); CLASS(fd_raw, f)(fd);
long err = -EBADF; long err;
if (!fd_file(f)) if (fd_empty(f))
goto out; return -EBADF;
if (unlikely(fd_file(f)->f_mode & FMODE_PATH)) { if (unlikely(fd_file(f)->f_mode & FMODE_PATH)) {
if (!check_fcntl_cmd(cmd)) if (!check_fcntl_cmd(cmd))
goto out1; return -EBADF;
} }
err = security_file_fcntl(fd_file(f), cmd, arg); err = security_file_fcntl(fd_file(f), cmd, arg);
if (!err) if (!err)
err = do_fcntl(fd, cmd, arg, fd_file(f)); err = do_fcntl(fd, cmd, arg, fd_file(f));
out1:
fdput(f);
out:
return err; return err;
} }
@ -596,21 +593,21 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
unsigned long, arg) unsigned long, arg)
{ {
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
struct fd f = fdget_raw(fd); CLASS(fd_raw, f)(fd);
struct flock64 flock; struct flock64 flock;
long err = -EBADF; long err;
if (!fd_file(f)) if (fd_empty(f))
goto out; return -EBADF;
if (unlikely(fd_file(f)->f_mode & FMODE_PATH)) { if (unlikely(fd_file(f)->f_mode & FMODE_PATH)) {
if (!check_fcntl_cmd(cmd)) if (!check_fcntl_cmd(cmd))
goto out1; return -EBADF;
} }
err = security_file_fcntl(fd_file(f), cmd, arg); err = security_file_fcntl(fd_file(f), cmd, arg);
if (err) if (err)
goto out1; return err;
switch (cmd) { switch (cmd) {
case F_GETLK64: case F_GETLK64:
@ -635,9 +632,6 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
err = do_fcntl(fd, cmd, arg, fd_file(f)); err = do_fcntl(fd, cmd, arg, fd_file(f));
break; break;
} }
out1:
fdput(f);
out:
return err; return err;
} }
#endif #endif
@ -733,21 +727,21 @@ static int fixup_compat_flock(struct flock *flock)
static long do_compat_fcntl64(unsigned int fd, unsigned int cmd, static long do_compat_fcntl64(unsigned int fd, unsigned int cmd,
compat_ulong_t arg) compat_ulong_t arg)
{ {
struct fd f = fdget_raw(fd); CLASS(fd_raw, f)(fd);
struct flock flock; struct flock flock;
long err = -EBADF; long err;
if (!fd_file(f)) if (fd_empty(f))
return err; return -EBADF;
if (unlikely(fd_file(f)->f_mode & FMODE_PATH)) { if (unlikely(fd_file(f)->f_mode & FMODE_PATH)) {
if (!check_fcntl_cmd(cmd)) if (!check_fcntl_cmd(cmd))
goto out_put; return -EBADF;
} }
err = security_file_fcntl(fd_file(f), cmd, arg); err = security_file_fcntl(fd_file(f), cmd, arg);
if (err) if (err)
goto out_put; return err;
switch (cmd) { switch (cmd) {
case F_GETLK: case F_GETLK:
@ -790,8 +784,6 @@ static long do_compat_fcntl64(unsigned int fd, unsigned int cmd,
err = do_fcntl(fd, cmd, arg, fd_file(f)); err = do_fcntl(fd, cmd, arg, fd_file(f));
break; break;
} }
out_put:
fdput(f);
return err; return err;
} }

View File

@ -2503,26 +2503,22 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
} }
} else { } else {
/* Caller must check execute permissions on the starting path component */ /* Caller must check execute permissions on the starting path component */
struct fd f = fdget_raw(nd->dfd); CLASS(fd_raw, f)(nd->dfd);
struct dentry *dentry; struct dentry *dentry;
if (!fd_file(f)) if (fd_empty(f))
return ERR_PTR(-EBADF); return ERR_PTR(-EBADF);
if (flags & LOOKUP_LINKAT_EMPTY) { if (flags & LOOKUP_LINKAT_EMPTY) {
if (fd_file(f)->f_cred != current_cred() && if (fd_file(f)->f_cred != current_cred() &&
!ns_capable(fd_file(f)->f_cred->user_ns, CAP_DAC_READ_SEARCH)) { !ns_capable(fd_file(f)->f_cred->user_ns, CAP_DAC_READ_SEARCH))
fdput(f);
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
} }
}
dentry = fd_file(f)->f_path.dentry; dentry = fd_file(f)->f_path.dentry;
if (*s && unlikely(!d_can_lookup(dentry))) { if (*s && unlikely(!d_can_lookup(dentry)))
fdput(f);
return ERR_PTR(-ENOTDIR); return ERR_PTR(-ENOTDIR);
}
nd->path = fd_file(f)->f_path; nd->path = fd_file(f)->f_path;
if (flags & LOOKUP_RCU) { if (flags & LOOKUP_RCU) {
@ -2532,7 +2528,6 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
path_get(&nd->path); path_get(&nd->path);
nd->inode = nd->path.dentry->d_inode; nd->inode = nd->path.dentry->d_inode;
} }
fdput(f);
} }
/* For scoped-lookups we need to set the root to the dirfd as well. */ /* For scoped-lookups we need to set the root to the dirfd as well. */

View File

@ -580,23 +580,18 @@ SYSCALL_DEFINE1(chdir, const char __user *, filename)
SYSCALL_DEFINE1(fchdir, unsigned int, fd) SYSCALL_DEFINE1(fchdir, unsigned int, fd)
{ {
struct fd f = fdget_raw(fd); CLASS(fd_raw, f)(fd);
int error; int error;
error = -EBADF; if (fd_empty(f))
if (!fd_file(f)) return -EBADF;
goto out;
error = -ENOTDIR;
if (!d_can_lookup(fd_file(f)->f_path.dentry)) if (!d_can_lookup(fd_file(f)->f_path.dentry))
goto out_putf; return -ENOTDIR;
error = file_permission(fd_file(f), MAY_EXEC | MAY_CHDIR); error = file_permission(fd_file(f), MAY_EXEC | MAY_CHDIR);
if (!error) if (!error)
set_fs_pwd(current->fs, &fd_file(f)->f_path); set_fs_pwd(current->fs, &fd_file(f)->f_path);
out_putf:
fdput(f);
out:
return error; return error;
} }

View File

@ -976,21 +976,19 @@ SYSCALL_DEFINE4(quotactl_fd, unsigned int, fd, unsigned int, cmd,
struct super_block *sb; struct super_block *sb;
unsigned int cmds = cmd >> SUBCMDSHIFT; unsigned int cmds = cmd >> SUBCMDSHIFT;
unsigned int type = cmd & SUBCMDMASK; unsigned int type = cmd & SUBCMDMASK;
struct fd f; CLASS(fd_raw, f)(fd);
int ret; int ret;
f = fdget_raw(fd); if (fd_empty(f))
if (!fd_file(f))
return -EBADF; return -EBADF;
ret = -EINVAL;
if (type >= MAXQUOTAS) if (type >= MAXQUOTAS)
goto out; return -EINVAL;
if (quotactl_cmd_write(cmds)) { if (quotactl_cmd_write(cmds)) {
ret = mnt_want_write(fd_file(f)->f_path.mnt); ret = mnt_want_write(fd_file(f)->f_path.mnt);
if (ret) if (ret)
goto out; return ret;
} }
sb = fd_file(f)->f_path.mnt->mnt_sb; sb = fd_file(f)->f_path.mnt->mnt_sb;
@ -1008,7 +1006,5 @@ SYSCALL_DEFINE4(quotactl_fd, unsigned int, fd, unsigned int, cmd,
if (quotactl_cmd_write(cmds)) if (quotactl_cmd_write(cmds))
mnt_drop_write(fd_file(f)->f_path.mnt); mnt_drop_write(fd_file(f)->f_path.mnt);
out:
fdput(f);
return ret; return ret;
} }

View File

@ -114,13 +114,11 @@ int user_statfs(const char __user *pathname, struct kstatfs *st)
int fd_statfs(int fd, struct kstatfs *st) int fd_statfs(int fd, struct kstatfs *st)
{ {
struct fd f = fdget_raw(fd); CLASS(fd_raw, f)(fd);
int error = -EBADF;
if (fd_file(f)) { if (fd_empty(f))
error = vfs_statfs(&fd_file(f)->f_path, st); return -EBADF;
fdput(f); return vfs_statfs(&fd_file(f)->f_path, st);
}
return error;
} }
static int do_statfs_native(struct kstatfs *st, struct statfs __user *p) static int do_statfs_native(struct kstatfs *st, struct statfs __user *p)

View File

@ -6966,14 +6966,11 @@ EXPORT_SYMBOL_GPL(cgroup_get_from_path);
*/ */
struct cgroup *cgroup_v1v2_get_from_fd(int fd) struct cgroup *cgroup_v1v2_get_from_fd(int fd)
{ {
struct cgroup *cgrp; CLASS(fd_raw, f)(fd);
struct fd f = fdget_raw(fd); if (fd_empty(f))
if (!fd_file(f))
return ERR_PTR(-EBADF); return ERR_PTR(-EBADF);
cgrp = cgroup_v1v2_get_from_file(fd_file(f)); return cgroup_v1v2_get_from_file(fd_file(f));
fdput(f);
return cgrp;
} }
/** /**

View File

@ -276,15 +276,12 @@ static struct landlock_ruleset *get_ruleset_from_fd(const int fd,
*/ */
static int get_path_from_fd(const s32 fd, struct path *const path) static int get_path_from_fd(const s32 fd, struct path *const path)
{ {
struct fd f; CLASS(fd_raw, f)(fd);
int err = 0;
BUILD_BUG_ON(!__same_type( BUILD_BUG_ON(!__same_type(
fd, ((struct landlock_path_beneath_attr *)NULL)->parent_fd)); fd, ((struct landlock_path_beneath_attr *)NULL)->parent_fd));
/* Handles O_PATH. */ if (fd_empty(f))
f = fdget_raw(fd);
if (!fd_file(f))
return -EBADF; return -EBADF;
/* /*
* Forbids ruleset FDs, internal filesystems (e.g. nsfs), including * Forbids ruleset FDs, internal filesystems (e.g. nsfs), including
@ -295,16 +292,12 @@ static int get_path_from_fd(const s32 fd, struct path *const path)
(fd_file(f)->f_path.mnt->mnt_flags & MNT_INTERNAL) || (fd_file(f)->f_path.mnt->mnt_flags & MNT_INTERNAL) ||
(fd_file(f)->f_path.dentry->d_sb->s_flags & SB_NOUSER) || (fd_file(f)->f_path.dentry->d_sb->s_flags & SB_NOUSER) ||
d_is_negative(fd_file(f)->f_path.dentry) || d_is_negative(fd_file(f)->f_path.dentry) ||
IS_PRIVATE(d_backing_inode(fd_file(f)->f_path.dentry))) { IS_PRIVATE(d_backing_inode(fd_file(f)->f_path.dentry)))
err = -EBADFD; return -EBADFD;
goto out_fdput;
}
*path = fd_file(f)->f_path; *path = fd_file(f)->f_path;
path_get(path); path_get(path);
return 0;
out_fdput:
fdput(f);
return err;
} }
static int add_rule_path_beneath(struct landlock_ruleset *const ruleset, static int add_rule_path_beneath(struct landlock_ruleset *const ruleset,