fdget(), more trivial conversions

all failure exits prior to fdget() leave the scope, all matching fdput()
are immediately followed by leaving the scope.

[xfs_ioc_commit_range() chunk moved here as well]

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-07-19 21:19:02 -04:00
parent 6348be02ee
commit 8152f82010
26 changed files with 202 additions and 418 deletions

View File

@ -1615,7 +1615,6 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
struct ucma_event *uevent, *tmp; struct ucma_event *uevent, *tmp;
struct ucma_context *ctx; struct ucma_context *ctx;
LIST_HEAD(event_list); LIST_HEAD(event_list);
struct fd f;
struct ucma_file *cur_file; struct ucma_file *cur_file;
int ret = 0; int ret = 0;
@ -1623,21 +1622,17 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
return -EFAULT; return -EFAULT;
/* Get current fd to protect against it being closed */ /* Get current fd to protect against it being closed */
f = fdget(cmd.fd); CLASS(fd, f)(cmd.fd);
if (!fd_file(f)) if (fd_empty(f))
return -ENOENT; return -ENOENT;
if (fd_file(f)->f_op != &ucma_fops) { if (fd_file(f)->f_op != &ucma_fops)
ret = -EINVAL; return -EINVAL;
goto file_put;
}
cur_file = fd_file(f)->private_data; cur_file = fd_file(f)->private_data;
/* Validate current fd and prevent destruction of id. */ /* Validate current fd and prevent destruction of id. */
ctx = ucma_get_ctx(cur_file, cmd.id); ctx = ucma_get_ctx(cur_file, cmd.id);
if (IS_ERR(ctx)) { if (IS_ERR(ctx))
ret = PTR_ERR(ctx); return PTR_ERR(ctx);
goto file_put;
}
rdma_lock_handler(ctx->cm_id); rdma_lock_handler(ctx->cm_id);
/* /*
@ -1678,8 +1673,6 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
err_unlock: err_unlock:
rdma_unlock_handler(ctx->cm_id); rdma_unlock_handler(ctx->cm_id);
ucma_put_ctx(ctx); ucma_put_ctx(ctx);
file_put:
fdput(f);
return ret; return ret;
} }

View File

@ -104,15 +104,14 @@ static int vfio_group_ioctl_set_container(struct vfio_group *group,
{ {
struct vfio_container *container; struct vfio_container *container;
struct iommufd_ctx *iommufd; struct iommufd_ctx *iommufd;
struct fd f;
int ret; int ret;
int fd; int fd;
if (get_user(fd, arg)) if (get_user(fd, arg))
return -EFAULT; return -EFAULT;
f = fdget(fd); CLASS(fd, f)(fd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
mutex_lock(&group->group_lock); mutex_lock(&group->group_lock);
@ -153,7 +152,6 @@ static int vfio_group_ioctl_set_container(struct vfio_group *group,
out_unlock: out_unlock:
mutex_unlock(&group->group_lock); mutex_unlock(&group->group_lock);
fdput(f);
return ret; return ret;
} }

View File

@ -2415,8 +2415,6 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
static int do_epoll_wait(int epfd, struct epoll_event __user *events, static int do_epoll_wait(int epfd, struct epoll_event __user *events,
int maxevents, struct timespec64 *to) int maxevents, struct timespec64 *to)
{ {
int error;
struct fd f;
struct eventpoll *ep; struct eventpoll *ep;
/* The maximum number of event must be greater than zero */ /* The maximum number of event must be greater than zero */
@ -2428,17 +2426,16 @@ static int do_epoll_wait(int epfd, struct epoll_event __user *events,
return -EFAULT; return -EFAULT;
/* Get the "struct file *" for the eventpoll file */ /* Get the "struct file *" for the eventpoll file */
f = fdget(epfd); CLASS(fd, f)(epfd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
/* /*
* We have to check that the file structure underneath the fd * We have to check that the file structure underneath the fd
* the user passed to us _is_ an eventpoll file. * the user passed to us _is_ an eventpoll file.
*/ */
error = -EINVAL;
if (!is_file_epoll(fd_file(f))) if (!is_file_epoll(fd_file(f)))
goto error_fput; return -EINVAL;
/* /*
* At this point it is safe to assume that the "private_data" contains * At this point it is safe to assume that the "private_data" contains
@ -2447,11 +2444,7 @@ static int do_epoll_wait(int epfd, struct epoll_event __user *events,
ep = fd_file(f)->private_data; ep = fd_file(f)->private_data;
/* Time to fish for events ... */ /* Time to fish for events ... */
error = ep_poll(ep, events, maxevents, to); return ep_poll(ep, events, maxevents, to);
error_fput:
fdput(f);
return error;
} }
SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events, SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,

View File

@ -1330,7 +1330,6 @@ group_extend_out:
case EXT4_IOC_MOVE_EXT: { case EXT4_IOC_MOVE_EXT: {
struct move_extent me; struct move_extent me;
struct fd donor;
int err; int err;
if (!(filp->f_mode & FMODE_READ) || if (!(filp->f_mode & FMODE_READ) ||
@ -1342,30 +1341,26 @@ group_extend_out:
return -EFAULT; return -EFAULT;
me.moved_len = 0; me.moved_len = 0;
donor = fdget(me.donor_fd); CLASS(fd, donor)(me.donor_fd);
if (!fd_file(donor)) if (fd_empty(donor))
return -EBADF; return -EBADF;
if (!(fd_file(donor)->f_mode & FMODE_WRITE)) { if (!(fd_file(donor)->f_mode & FMODE_WRITE))
err = -EBADF; return -EBADF;
goto mext_out;
}
if (ext4_has_feature_bigalloc(sb)) { if (ext4_has_feature_bigalloc(sb)) {
ext4_msg(sb, KERN_ERR, ext4_msg(sb, KERN_ERR,
"Online defrag not supported with bigalloc"); "Online defrag not supported with bigalloc");
err = -EOPNOTSUPP; return -EOPNOTSUPP;
goto mext_out;
} else if (IS_DAX(inode)) { } else if (IS_DAX(inode)) {
ext4_msg(sb, KERN_ERR, ext4_msg(sb, KERN_ERR,
"Online defrag not supported with DAX"); "Online defrag not supported with DAX");
err = -EOPNOTSUPP; return -EOPNOTSUPP;
goto mext_out;
} }
err = mnt_want_write_file(filp); err = mnt_want_write_file(filp);
if (err) if (err)
goto mext_out; return err;
err = ext4_move_extents(filp, fd_file(donor), me.orig_start, err = ext4_move_extents(filp, fd_file(donor), me.orig_start,
me.donor_start, me.len, &me.moved_len); me.donor_start, me.len, &me.moved_len);
@ -1374,8 +1369,6 @@ group_extend_out:
if (copy_to_user((struct move_extent __user *)arg, if (copy_to_user((struct move_extent __user *)arg,
&me, sizeof(me))) &me, sizeof(me)))
err = -EFAULT; err = -EFAULT;
mext_out:
fdput(donor);
return err; return err;
} }

View File

@ -3038,32 +3038,27 @@ out:
static int __f2fs_ioc_move_range(struct file *filp, static int __f2fs_ioc_move_range(struct file *filp,
struct f2fs_move_range *range) struct f2fs_move_range *range)
{ {
struct fd dst;
int err; int err;
if (!(filp->f_mode & FMODE_READ) || if (!(filp->f_mode & FMODE_READ) ||
!(filp->f_mode & FMODE_WRITE)) !(filp->f_mode & FMODE_WRITE))
return -EBADF; return -EBADF;
dst = fdget(range->dst_fd); CLASS(fd, dst)(range->dst_fd);
if (!fd_file(dst)) if (fd_empty(dst))
return -EBADF; return -EBADF;
if (!(fd_file(dst)->f_mode & FMODE_WRITE)) { if (!(fd_file(dst)->f_mode & FMODE_WRITE))
err = -EBADF; return -EBADF;
goto err_out;
}
err = mnt_want_write_file(filp); err = mnt_want_write_file(filp);
if (err) if (err)
goto err_out; return err;
err = f2fs_move_file_range(filp, range->pos_in, fd_file(dst), err = f2fs_move_file_range(filp, range->pos_in, fd_file(dst),
range->pos_out, range->len); range->pos_out, range->len);
mnt_drop_write_file(filp); mnt_drop_write_file(filp);
err_out:
fdput(dst);
return err; return err;
} }

View File

@ -349,7 +349,6 @@ SYSCALL_DEFINE5(fsconfig,
int, aux) int, aux)
{ {
struct fs_context *fc; struct fs_context *fc;
struct fd f;
int ret; int ret;
int lookup_flags = 0; int lookup_flags = 0;
@ -392,12 +391,11 @@ SYSCALL_DEFINE5(fsconfig,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
f = fdget(fd); CLASS(fd, f)(fd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
ret = -EINVAL;
if (fd_file(f)->f_op != &fscontext_fops) if (fd_file(f)->f_op != &fscontext_fops)
goto out_f; return -EINVAL;
fc = fd_file(f)->private_data; fc = fd_file(f)->private_data;
if (fc->ops == &legacy_fs_context_ops) { if (fc->ops == &legacy_fs_context_ops) {
@ -407,17 +405,14 @@ SYSCALL_DEFINE5(fsconfig,
case FSCONFIG_SET_PATH_EMPTY: case FSCONFIG_SET_PATH_EMPTY:
case FSCONFIG_SET_FD: case FSCONFIG_SET_FD:
case FSCONFIG_CMD_CREATE_EXCL: case FSCONFIG_CMD_CREATE_EXCL:
ret = -EOPNOTSUPP; return -EOPNOTSUPP;
goto out_f;
} }
} }
if (_key) { if (_key) {
param.key = strndup_user(_key, 256); param.key = strndup_user(_key, 256);
if (IS_ERR(param.key)) { if (IS_ERR(param.key))
ret = PTR_ERR(param.key); return PTR_ERR(param.key);
goto out_f;
}
} }
switch (cmd) { switch (cmd) {
@ -496,7 +491,5 @@ SYSCALL_DEFINE5(fsconfig,
} }
out_key: out_key:
kfree(param.key); kfree(param.key);
out_f:
fdput(f);
return ret; return ret;
} }

View File

@ -2371,13 +2371,12 @@ static long fuse_dev_ioctl_clone(struct file *file, __u32 __user *argp)
int res; int res;
int oldfd; int oldfd;
struct fuse_dev *fud = NULL; struct fuse_dev *fud = NULL;
struct fd f;
if (get_user(oldfd, argp)) if (get_user(oldfd, argp))
return -EFAULT; return -EFAULT;
f = fdget(oldfd); CLASS(fd, f)(oldfd);
if (!fd_file(f)) if (fd_empty(f))
return -EINVAL; return -EINVAL;
/* /*
@ -2394,7 +2393,6 @@ static long fuse_dev_ioctl_clone(struct file *file, __u32 __user *argp)
mutex_unlock(&fuse_mutex); mutex_unlock(&fuse_mutex);
} }
fdput(f);
return res; return res;
} }

View File

@ -2136,7 +2136,6 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
{ {
int can_sleep, error, type; int can_sleep, error, type;
struct file_lock fl; struct file_lock fl;
struct fd f;
/* /*
* LOCK_MAND locks were broken for a long time in that they never * LOCK_MAND locks were broken for a long time in that they never
@ -2155,19 +2154,18 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
if (type < 0) if (type < 0)
return type; return type;
error = -EBADF; CLASS(fd, f)(fd);
f = fdget(fd); if (fd_empty(f))
if (!fd_file(f)) return -EBADF;
return error;
if (type != F_UNLCK && !(fd_file(f)->f_mode & (FMODE_READ | FMODE_WRITE))) if (type != F_UNLCK && !(fd_file(f)->f_mode & (FMODE_READ | FMODE_WRITE)))
goto out_putf; return -EBADF;
flock_make_lock(fd_file(f), &fl, type); flock_make_lock(fd_file(f), &fl, type);
error = security_file_lock(fd_file(f), fl.c.flc_type); error = security_file_lock(fd_file(f), fl.c.flc_type);
if (error) if (error)
goto out_putf; return error;
can_sleep = !(cmd & LOCK_NB); can_sleep = !(cmd & LOCK_NB);
if (can_sleep) if (can_sleep)
@ -2181,9 +2179,6 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
error = locks_lock_file_wait(fd_file(f), &fl); error = locks_lock_file_wait(fd_file(f), &fl);
locks_release_private(&fl); locks_release_private(&fl);
out_putf:
fdput(f);
return error; return error;
} }

View File

@ -4105,7 +4105,6 @@ SYSCALL_DEFINE3(fsmount, int, fs_fd, unsigned int, flags,
struct file *file; struct file *file;
struct path newmount; struct path newmount;
struct mount *mnt; struct mount *mnt;
struct fd f;
unsigned int mnt_flags = 0; unsigned int mnt_flags = 0;
long ret; long ret;
@ -4133,19 +4132,18 @@ SYSCALL_DEFINE3(fsmount, int, fs_fd, unsigned int, flags,
return -EINVAL; return -EINVAL;
} }
f = fdget(fs_fd); CLASS(fd, f)(fs_fd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
ret = -EINVAL;
if (fd_file(f)->f_op != &fscontext_fops) if (fd_file(f)->f_op != &fscontext_fops)
goto err_fsfd; return -EINVAL;
fc = fd_file(f)->private_data; fc = fd_file(f)->private_data;
ret = mutex_lock_interruptible(&fc->uapi_mutex); ret = mutex_lock_interruptible(&fc->uapi_mutex);
if (ret < 0) if (ret < 0)
goto err_fsfd; return ret;
/* There must be a valid superblock or we can't mount it */ /* There must be a valid superblock or we can't mount it */
ret = -EINVAL; ret = -EINVAL;
@ -4212,8 +4210,6 @@ err_path:
path_put(&newmount); path_put(&newmount);
err_unlock: err_unlock:
mutex_unlock(&fc->uapi_mutex); mutex_unlock(&fc->uapi_mutex);
err_fsfd:
fdput(f);
return ret; return ret;
} }
@ -4668,10 +4664,8 @@ out:
static int build_mount_idmapped(const struct mount_attr *attr, size_t usize, static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
struct mount_kattr *kattr, unsigned int flags) struct mount_kattr *kattr, unsigned int flags)
{ {
int err = 0;
struct ns_common *ns; struct ns_common *ns;
struct user_namespace *mnt_userns; struct user_namespace *mnt_userns;
struct fd f;
if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP)) if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP))
return 0; return 0;
@ -4687,20 +4681,16 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
if (attr->userns_fd > INT_MAX) if (attr->userns_fd > INT_MAX)
return -EINVAL; return -EINVAL;
f = fdget(attr->userns_fd); CLASS(fd, f)(attr->userns_fd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
if (!proc_ns_file(fd_file(f))) { if (!proc_ns_file(fd_file(f)))
err = -EINVAL; return -EINVAL;
goto out_fput;
}
ns = get_proc_ns(file_inode(fd_file(f))); ns = get_proc_ns(file_inode(fd_file(f)));
if (ns->ops->type != CLONE_NEWUSER) { if (ns->ops->type != CLONE_NEWUSER)
err = -EINVAL; return -EINVAL;
goto out_fput;
}
/* /*
* The initial idmapping cannot be used to create an idmapped * The initial idmapping cannot be used to create an idmapped
@ -4711,22 +4701,15 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
* result. * result.
*/ */
mnt_userns = container_of(ns, struct user_namespace, ns); mnt_userns = container_of(ns, struct user_namespace, ns);
if (mnt_userns == &init_user_ns) { if (mnt_userns == &init_user_ns)
err = -EPERM; return -EPERM;
goto out_fput;
}
/* We're not controlling the target namespace. */ /* We're not controlling the target namespace. */
if (!ns_capable(mnt_userns, CAP_SYS_ADMIN)) { if (!ns_capable(mnt_userns, CAP_SYS_ADMIN))
err = -EPERM; return -EPERM;
goto out_fput;
}
kattr->mnt_userns = get_user_ns(mnt_userns); kattr->mnt_userns = get_user_ns(mnt_userns);
return 0;
out_fput:
fdput(f);
return err;
} }
static int build_mount_kattr(const struct mount_attr *attr, size_t usize, static int build_mount_kattr(const struct mount_attr *attr, size_t usize,

View File

@ -1677,7 +1677,6 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
struct inode *inode = NULL; struct inode *inode = NULL;
struct vfsmount *mnt = NULL; struct vfsmount *mnt = NULL;
struct fsnotify_group *group; struct fsnotify_group *group;
struct fd f;
struct path path; struct path path;
struct fan_fsid __fsid, *fsid = NULL; struct fan_fsid __fsid, *fsid = NULL;
u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS; u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS;
@ -1747,14 +1746,13 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
umask = FANOTIFY_EVENT_FLAGS; umask = FANOTIFY_EVENT_FLAGS;
} }
f = fdget(fanotify_fd); CLASS(fd, f)(fanotify_fd);
if (unlikely(!fd_file(f))) if (fd_empty(f))
return -EBADF; return -EBADF;
/* verify that this is indeed an fanotify instance */ /* verify that this is indeed an fanotify instance */
ret = -EINVAL;
if (unlikely(fd_file(f)->f_op != &fanotify_fops)) if (unlikely(fd_file(f)->f_op != &fanotify_fops))
goto fput_and_out; return -EINVAL;
group = fd_file(f)->private_data; group = fd_file(f)->private_data;
/* /*
@ -1762,23 +1760,21 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
* marks. This also includes setting up such marks by a group that * marks. This also includes setting up such marks by a group that
* was initialized by an unprivileged user. * was initialized by an unprivileged user.
*/ */
ret = -EPERM;
if ((!capable(CAP_SYS_ADMIN) || if ((!capable(CAP_SYS_ADMIN) ||
FAN_GROUP_FLAG(group, FANOTIFY_UNPRIV)) && FAN_GROUP_FLAG(group, FANOTIFY_UNPRIV)) &&
mark_type != FAN_MARK_INODE) mark_type != FAN_MARK_INODE)
goto fput_and_out; return -EPERM;
/* /*
* Permission events require minimum priority FAN_CLASS_CONTENT. * Permission events require minimum priority FAN_CLASS_CONTENT.
*/ */
ret = -EINVAL;
if (mask & FANOTIFY_PERM_EVENTS && if (mask & FANOTIFY_PERM_EVENTS &&
group->priority < FSNOTIFY_PRIO_CONTENT) group->priority < FSNOTIFY_PRIO_CONTENT)
goto fput_and_out; return -EINVAL;
if (mask & FAN_FS_ERROR && if (mask & FAN_FS_ERROR &&
mark_type != FAN_MARK_FILESYSTEM) mark_type != FAN_MARK_FILESYSTEM)
goto fput_and_out; return -EINVAL;
/* /*
* Evictable is only relevant for inode marks, because only inode object * Evictable is only relevant for inode marks, because only inode object
@ -1786,7 +1782,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
*/ */
if (flags & FAN_MARK_EVICTABLE && if (flags & FAN_MARK_EVICTABLE &&
mark_type != FAN_MARK_INODE) mark_type != FAN_MARK_INODE)
goto fput_and_out; return -EINVAL;
/* /*
* Events that do not carry enough information to report * Events that do not carry enough information to report
@ -1798,7 +1794,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS); fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS);
if (mask & ~(FANOTIFY_FD_EVENTS|FANOTIFY_EVENT_FLAGS) && if (mask & ~(FANOTIFY_FD_EVENTS|FANOTIFY_EVENT_FLAGS) &&
(!fid_mode || mark_type == FAN_MARK_MOUNT)) (!fid_mode || mark_type == FAN_MARK_MOUNT))
goto fput_and_out; return -EINVAL;
/* /*
* FAN_RENAME uses special info type records to report the old and * FAN_RENAME uses special info type records to report the old and
@ -1806,23 +1802,22 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
* useful and was not implemented. * useful and was not implemented.
*/ */
if (mask & FAN_RENAME && !(fid_mode & FAN_REPORT_NAME)) if (mask & FAN_RENAME && !(fid_mode & FAN_REPORT_NAME))
goto fput_and_out; return -EINVAL;
if (mark_cmd == FAN_MARK_FLUSH) { if (mark_cmd == FAN_MARK_FLUSH) {
ret = 0;
if (mark_type == FAN_MARK_MOUNT) if (mark_type == FAN_MARK_MOUNT)
fsnotify_clear_vfsmount_marks_by_group(group); fsnotify_clear_vfsmount_marks_by_group(group);
else if (mark_type == FAN_MARK_FILESYSTEM) else if (mark_type == FAN_MARK_FILESYSTEM)
fsnotify_clear_sb_marks_by_group(group); fsnotify_clear_sb_marks_by_group(group);
else else
fsnotify_clear_inode_marks_by_group(group); fsnotify_clear_inode_marks_by_group(group);
goto fput_and_out; return 0;
} }
ret = fanotify_find_path(dfd, pathname, &path, flags, ret = fanotify_find_path(dfd, pathname, &path, flags,
(mask & ALL_FSNOTIFY_EVENTS), obj_type); (mask & ALL_FSNOTIFY_EVENTS), obj_type);
if (ret) if (ret)
goto fput_and_out; return ret;
if (mark_cmd == FAN_MARK_ADD) { if (mark_cmd == FAN_MARK_ADD) {
ret = fanotify_events_supported(group, &path, mask, flags); ret = fanotify_events_supported(group, &path, mask, flags);
@ -1901,8 +1896,6 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
path_put_and_out: path_put_and_out:
path_put(&path); path_put(&path);
fput_and_out:
fdput(f);
return ret; return ret;
} }

View File

@ -732,7 +732,6 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
struct fsnotify_group *group; struct fsnotify_group *group;
struct inode *inode; struct inode *inode;
struct path path; struct path path;
struct fd f;
int ret; int ret;
unsigned flags = 0; unsigned flags = 0;
@ -752,21 +751,17 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
if (unlikely(!(mask & ALL_INOTIFY_BITS))) if (unlikely(!(mask & ALL_INOTIFY_BITS)))
return -EINVAL; return -EINVAL;
f = fdget(fd); CLASS(fd, f)(fd);
if (unlikely(!fd_file(f))) if (fd_empty(f))
return -EBADF; return -EBADF;
/* IN_MASK_ADD and IN_MASK_CREATE don't make sense together */ /* IN_MASK_ADD and IN_MASK_CREATE don't make sense together */
if (unlikely((mask & IN_MASK_ADD) && (mask & IN_MASK_CREATE))) { if (unlikely((mask & IN_MASK_ADD) && (mask & IN_MASK_CREATE)))
ret = -EINVAL; return -EINVAL;
goto fput_and_out;
}
/* verify that this is indeed an inotify instance */ /* verify that this is indeed an inotify instance */
if (unlikely(fd_file(f)->f_op != &inotify_fops)) { if (unlikely(fd_file(f)->f_op != &inotify_fops))
ret = -EINVAL; return -EINVAL;
goto fput_and_out;
}
if (!(mask & IN_DONT_FOLLOW)) if (!(mask & IN_DONT_FOLLOW))
flags |= LOOKUP_FOLLOW; flags |= LOOKUP_FOLLOW;
@ -776,7 +771,7 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
ret = inotify_find_inode(pathname, &path, flags, ret = inotify_find_inode(pathname, &path, flags,
(mask & IN_ALL_EVENTS)); (mask & IN_ALL_EVENTS));
if (ret) if (ret)
goto fput_and_out; return ret;
/* inode held in place by reference to path; group by fget on fd */ /* inode held in place by reference to path; group by fget on fd */
inode = path.dentry->d_inode; inode = path.dentry->d_inode;
@ -785,8 +780,6 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
/* create/update an inode mark */ /* create/update an inode mark */
ret = inotify_update_watch(group, inode, mask); ret = inotify_update_watch(group, inode, mask);
path_put(&path); path_put(&path);
fput_and_out:
fdput(f);
return ret; return ret;
} }

View File

@ -1765,7 +1765,6 @@ static ssize_t o2hb_region_dev_store(struct config_item *item,
long fd; long fd;
int sectsize; int sectsize;
char *p = (char *)page; char *p = (char *)page;
struct fd f;
ssize_t ret = -EINVAL; ssize_t ret = -EINVAL;
int live_threshold; int live_threshold;
@ -1784,23 +1783,23 @@ static ssize_t o2hb_region_dev_store(struct config_item *item,
if (fd < 0 || fd >= INT_MAX) if (fd < 0 || fd >= INT_MAX)
return -EINVAL; return -EINVAL;
f = fdget(fd); CLASS(fd, f)(fd);
if (fd_file(f) == NULL) if (fd_empty(f))
return -EINVAL; return -EINVAL;
if (reg->hr_blocks == 0 || reg->hr_start_block == 0 || if (reg->hr_blocks == 0 || reg->hr_start_block == 0 ||
reg->hr_block_bytes == 0) reg->hr_block_bytes == 0)
goto out2; return -EINVAL;
if (!S_ISBLK(fd_file(f)->f_mapping->host->i_mode)) if (!S_ISBLK(fd_file(f)->f_mapping->host->i_mode))
goto out2; return -EINVAL;
reg->hr_bdev_file = bdev_file_open_by_dev(fd_file(f)->f_mapping->host->i_rdev, reg->hr_bdev_file = bdev_file_open_by_dev(fd_file(f)->f_mapping->host->i_rdev,
BLK_OPEN_WRITE | BLK_OPEN_READ, NULL, NULL); BLK_OPEN_WRITE | BLK_OPEN_READ, NULL, NULL);
if (IS_ERR(reg->hr_bdev_file)) { if (IS_ERR(reg->hr_bdev_file)) {
ret = PTR_ERR(reg->hr_bdev_file); ret = PTR_ERR(reg->hr_bdev_file);
reg->hr_bdev_file = NULL; reg->hr_bdev_file = NULL;
goto out2; return ret;
} }
sectsize = bdev_logical_block_size(reg_bdev(reg)); sectsize = bdev_logical_block_size(reg_bdev(reg));
@ -1906,8 +1905,6 @@ out3:
fput(reg->hr_bdev_file); fput(reg->hr_bdev_file);
reg->hr_bdev_file = NULL; reg->hr_bdev_file = NULL;
} }
out2:
fdput(f);
return ret; return ret;
} }

View File

@ -187,19 +187,13 @@ long do_ftruncate(struct file *file, loff_t length, int small)
long do_sys_ftruncate(unsigned int fd, loff_t length, int small) long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
{ {
struct fd f;
int error;
if (length < 0) if (length < 0)
return -EINVAL; return -EINVAL;
f = fdget(fd); CLASS(fd, f)(fd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
error = do_ftruncate(fd_file(f), length, small); return do_ftruncate(fd_file(f), length, small);
fdput(f);
return error;
} }
SYSCALL_DEFINE2(ftruncate, unsigned int, fd, off_t, length) SYSCALL_DEFINE2(ftruncate, unsigned int, fd, off_t, length)

View File

@ -745,21 +745,17 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
ssize_t ksys_pread64(unsigned int fd, char __user *buf, size_t count, ssize_t ksys_pread64(unsigned int fd, char __user *buf, size_t count,
loff_t pos) loff_t pos)
{ {
struct fd f;
ssize_t ret = -EBADF;
if (pos < 0) if (pos < 0)
return -EINVAL; return -EINVAL;
f = fdget(fd); CLASS(fd, f)(fd);
if (fd_file(f)) { if (fd_empty(f))
ret = -ESPIPE; return -EBADF;
if (fd_file(f)->f_mode & FMODE_PREAD)
ret = vfs_read(fd_file(f), buf, count, &pos);
fdput(f);
}
return ret; if (fd_file(f)->f_mode & FMODE_PREAD)
return vfs_read(fd_file(f), buf, count, &pos);
return -ESPIPE;
} }
SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf, SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
@ -779,21 +775,17 @@ COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, buf,
ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf, ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf,
size_t count, loff_t pos) size_t count, loff_t pos)
{ {
struct fd f;
ssize_t ret = -EBADF;
if (pos < 0) if (pos < 0)
return -EINVAL; return -EINVAL;
f = fdget(fd); CLASS(fd, f)(fd);
if (fd_file(f)) { if (fd_empty(f))
ret = -ESPIPE; return -EBADF;
if (fd_file(f)->f_mode & FMODE_PWRITE)
ret = vfs_write(fd_file(f), buf, count, &pos);
fdput(f);
}
return ret; if (fd_file(f)->f_mode & FMODE_PWRITE)
return vfs_write(fd_file(f), buf, count, &pos);
return -ESPIPE;
} }
SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf, SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
@ -1307,7 +1299,6 @@ COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd,
static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
size_t count, loff_t max) size_t count, loff_t max)
{ {
struct fd in, out;
struct inode *in_inode, *out_inode; struct inode *in_inode, *out_inode;
struct pipe_inode_info *opipe; struct pipe_inode_info *opipe;
loff_t pos; loff_t pos;
@ -1318,35 +1309,32 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
/* /*
* Get input file, and verify that it is ok.. * Get input file, and verify that it is ok..
*/ */
retval = -EBADF; CLASS(fd, in)(in_fd);
in = fdget(in_fd); if (fd_empty(in))
if (!fd_file(in)) return -EBADF;
goto out;
if (!(fd_file(in)->f_mode & FMODE_READ)) if (!(fd_file(in)->f_mode & FMODE_READ))
goto fput_in; return -EBADF;
retval = -ESPIPE;
if (!ppos) { if (!ppos) {
pos = fd_file(in)->f_pos; pos = fd_file(in)->f_pos;
} else { } else {
pos = *ppos; pos = *ppos;
if (!(fd_file(in)->f_mode & FMODE_PREAD)) if (!(fd_file(in)->f_mode & FMODE_PREAD))
goto fput_in; return -ESPIPE;
} }
retval = rw_verify_area(READ, fd_file(in), &pos, count); retval = rw_verify_area(READ, fd_file(in), &pos, count);
if (retval < 0) if (retval < 0)
goto fput_in; return retval;
if (count > MAX_RW_COUNT) if (count > MAX_RW_COUNT)
count = MAX_RW_COUNT; count = MAX_RW_COUNT;
/* /*
* Get output file, and verify that it is ok.. * Get output file, and verify that it is ok..
*/ */
retval = -EBADF; CLASS(fd, out)(out_fd);
out = fdget(out_fd); if (fd_empty(out))
if (!fd_file(out)) return -EBADF;
goto fput_in;
if (!(fd_file(out)->f_mode & FMODE_WRITE)) if (!(fd_file(out)->f_mode & FMODE_WRITE))
goto fput_out; return -EBADF;
in_inode = file_inode(fd_file(in)); in_inode = file_inode(fd_file(in));
out_inode = file_inode(fd_file(out)); out_inode = file_inode(fd_file(out));
out_pos = fd_file(out)->f_pos; out_pos = fd_file(out)->f_pos;
@ -1355,9 +1343,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
if (unlikely(pos + count > max)) { if (unlikely(pos + count > max)) {
retval = -EOVERFLOW;
if (pos >= max) if (pos >= max)
goto fput_out; return -EOVERFLOW;
count = max - pos; count = max - pos;
} }
@ -1376,7 +1363,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
if (!opipe) { if (!opipe) {
retval = rw_verify_area(WRITE, fd_file(out), &out_pos, count); retval = rw_verify_area(WRITE, fd_file(out), &out_pos, count);
if (retval < 0) if (retval < 0)
goto fput_out; return retval;
retval = do_splice_direct(fd_file(in), &pos, fd_file(out), &out_pos, retval = do_splice_direct(fd_file(in), &pos, fd_file(out), &out_pos,
count, fl); count, fl);
} else { } else {
@ -1402,12 +1389,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
inc_syscw(current); inc_syscw(current);
if (pos > max) if (pos > max)
retval = -EOVERFLOW; retval = -EOVERFLOW;
fput_out:
fdput(out);
fput_in:
fdput(in);
out:
return retval; return retval;
} }

View File

@ -1622,27 +1622,22 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
int, fd_out, loff_t __user *, off_out, int, fd_out, loff_t __user *, off_out,
size_t, len, unsigned int, flags) size_t, len, unsigned int, flags)
{ {
struct fd in, out;
ssize_t error;
if (unlikely(!len)) if (unlikely(!len))
return 0; return 0;
if (unlikely(flags & ~SPLICE_F_ALL)) if (unlikely(flags & ~SPLICE_F_ALL))
return -EINVAL; return -EINVAL;
error = -EBADF; CLASS(fd, in)(fd_in);
in = fdget(fd_in); if (fd_empty(in))
if (fd_file(in)) { return -EBADF;
out = fdget(fd_out);
if (fd_file(out)) { CLASS(fd, out)(fd_out);
error = __do_splice(fd_file(in), off_in, fd_file(out), off_out, if (fd_empty(out))
return -EBADF;
return __do_splice(fd_file(in), off_in, fd_file(out), off_out,
len, flags); len, flags);
fdput(out);
}
fdput(in);
}
return error;
} }
/* /*
@ -1992,25 +1987,19 @@ ssize_t do_tee(struct file *in, struct file *out, size_t len,
SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
{ {
struct fd in, out;
ssize_t error;
if (unlikely(flags & ~SPLICE_F_ALL)) if (unlikely(flags & ~SPLICE_F_ALL))
return -EINVAL; return -EINVAL;
if (unlikely(!len)) if (unlikely(!len))
return 0; return 0;
error = -EBADF; CLASS(fd, in)(fdin);
in = fdget(fdin); if (fd_empty(in))
if (fd_file(in)) { return -EBADF;
out = fdget(fdout);
if (fd_file(out)) {
error = do_tee(fd_file(in), fd_file(out), len, flags);
fdput(out);
}
fdput(in);
}
return error; CLASS(fd, out)(fdout);
if (fd_empty(out))
return -EBADF;
return do_tee(fd_file(in), fd_file(out), len, flags);
} }

View File

@ -108,18 +108,13 @@ retry:
static int do_utimes_fd(int fd, struct timespec64 *times, int flags) static int do_utimes_fd(int fd, struct timespec64 *times, int flags)
{ {
struct fd f;
int error;
if (flags) if (flags)
return -EINVAL; return -EINVAL;
f = fdget(fd); CLASS(fd, f)(fd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
error = vfs_utimes(&fd_file(f)->f_path, times); return vfs_utimes(&fd_file(f)->f_path, times);
fdput(f);
return error;
} }
/* /*

View File

@ -813,8 +813,6 @@ xfs_ioc_exchange_range(
.file2 = file, .file2 = file,
}; };
struct xfs_exchange_range args; struct xfs_exchange_range args;
struct fd file1;
int error;
if (copy_from_user(&args, argp, sizeof(args))) if (copy_from_user(&args, argp, sizeof(args)))
return -EFAULT; return -EFAULT;
@ -828,14 +826,12 @@ xfs_ioc_exchange_range(
fxr.length = args.length; fxr.length = args.length;
fxr.flags = args.flags; fxr.flags = args.flags;
file1 = fdget(args.file1_fd); CLASS(fd, file1)(args.file1_fd);
if (!fd_file(file1)) if (fd_empty(file1))
return -EBADF; return -EBADF;
fxr.file1 = fd_file(file1); fxr.file1 = fd_file(file1);
error = xfs_exchange_range(&fxr); return xfs_exchange_range(&fxr);
fdput(file1);
return error;
} }
/* Opaque freshness blob for XFS_IOC_COMMIT_RANGE */ /* Opaque freshness blob for XFS_IOC_COMMIT_RANGE */
@ -909,8 +905,6 @@ xfs_ioc_commit_range(
struct xfs_commit_range_fresh *kern_f; struct xfs_commit_range_fresh *kern_f;
struct xfs_inode *ip2 = XFS_I(file_inode(file)); struct xfs_inode *ip2 = XFS_I(file_inode(file));
struct xfs_mount *mp = ip2->i_mount; struct xfs_mount *mp = ip2->i_mount;
struct fd file1;
int error;
kern_f = (struct xfs_commit_range_fresh *)&args.file2_freshness; kern_f = (struct xfs_commit_range_fresh *)&args.file2_freshness;
@ -934,12 +928,10 @@ xfs_ioc_commit_range(
fxr.file2_ctime.tv_sec = kern_f->file2_ctime; fxr.file2_ctime.tv_sec = kern_f->file2_ctime;
fxr.file2_ctime.tv_nsec = kern_f->file2_ctime_nsec; fxr.file2_ctime.tv_nsec = kern_f->file2_ctime_nsec;
file1 = fdget(args.file1_fd); CLASS(fd, file1)(args.file1_fd);
if (fd_empty(file1)) if (fd_empty(file1))
return -EBADF; return -EBADF;
fxr.file1 = fd_file(file1); fxr.file1 = fd_file(file1);
error = xfs_exchange_range(&fxr); return xfs_exchange_range(&fxr);
fdput(file1);
return error;
} }

View File

@ -881,41 +881,29 @@ xfs_ioc_swapext(
xfs_swapext_t *sxp) xfs_swapext_t *sxp)
{ {
xfs_inode_t *ip, *tip; xfs_inode_t *ip, *tip;
struct fd f, tmp;
int error = 0;
/* Pull information for the target fd */ /* Pull information for the target fd */
f = fdget((int)sxp->sx_fdtarget); CLASS(fd, f)((int)sxp->sx_fdtarget);
if (!fd_file(f)) { if (fd_empty(f))
error = -EINVAL; return -EINVAL;
goto out;
}
if (!(fd_file(f)->f_mode & FMODE_WRITE) || if (!(fd_file(f)->f_mode & FMODE_WRITE) ||
!(fd_file(f)->f_mode & FMODE_READ) || !(fd_file(f)->f_mode & FMODE_READ) ||
(fd_file(f)->f_flags & O_APPEND)) { (fd_file(f)->f_flags & O_APPEND))
error = -EBADF; return -EBADF;
goto out_put_file;
}
tmp = fdget((int)sxp->sx_fdtmp); CLASS(fd, tmp)((int)sxp->sx_fdtmp);
if (!fd_file(tmp)) { if (fd_empty(tmp))
error = -EINVAL; return -EINVAL;
goto out_put_file;
}
if (!(fd_file(tmp)->f_mode & FMODE_WRITE) || if (!(fd_file(tmp)->f_mode & FMODE_WRITE) ||
!(fd_file(tmp)->f_mode & FMODE_READ) || !(fd_file(tmp)->f_mode & FMODE_READ) ||
(fd_file(tmp)->f_flags & O_APPEND)) { (fd_file(tmp)->f_flags & O_APPEND))
error = -EBADF; return -EBADF;
goto out_put_tmp_file;
}
if (IS_SWAPFILE(file_inode(fd_file(f))) || if (IS_SWAPFILE(file_inode(fd_file(f))) ||
IS_SWAPFILE(file_inode(fd_file(tmp)))) { IS_SWAPFILE(file_inode(fd_file(tmp))))
error = -EINVAL; return -EINVAL;
goto out_put_tmp_file;
}
/* /*
* We need to ensure that the fds passed in point to XFS inodes * We need to ensure that the fds passed in point to XFS inodes
@ -923,37 +911,22 @@ xfs_ioc_swapext(
* control over what the user passes us here. * control over what the user passes us here.
*/ */
if (fd_file(f)->f_op != &xfs_file_operations || if (fd_file(f)->f_op != &xfs_file_operations ||
fd_file(tmp)->f_op != &xfs_file_operations) { fd_file(tmp)->f_op != &xfs_file_operations)
error = -EINVAL; return -EINVAL;
goto out_put_tmp_file;
}
ip = XFS_I(file_inode(fd_file(f))); ip = XFS_I(file_inode(fd_file(f)));
tip = XFS_I(file_inode(fd_file(tmp))); tip = XFS_I(file_inode(fd_file(tmp)));
if (ip->i_mount != tip->i_mount) { if (ip->i_mount != tip->i_mount)
error = -EINVAL; return -EINVAL;
goto out_put_tmp_file;
}
if (ip->i_ino == tip->i_ino) { if (ip->i_ino == tip->i_ino)
error = -EINVAL; return -EINVAL;
goto out_put_tmp_file;
}
if (xfs_is_shutdown(ip->i_mount)) { if (xfs_is_shutdown(ip->i_mount))
error = -EIO; return -EIO;
goto out_put_tmp_file;
}
error = xfs_swap_extents(ip, tip, sxp); return xfs_swap_extents(ip, tip, sxp);
out_put_tmp_file:
fdput(tmp);
out_put_file:
fdput(f);
out:
return error;
} }
static int static int

View File

@ -1063,7 +1063,6 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
size_t msg_len, unsigned int msg_prio, size_t msg_len, unsigned int msg_prio,
struct timespec64 *ts) struct timespec64 *ts)
{ {
struct fd f;
struct inode *inode; struct inode *inode;
struct ext_wait_queue wait; struct ext_wait_queue wait;
struct ext_wait_queue *receiver; struct ext_wait_queue *receiver;
@ -1084,37 +1083,27 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
audit_mq_sendrecv(mqdes, msg_len, msg_prio, ts); audit_mq_sendrecv(mqdes, msg_len, msg_prio, ts);
f = fdget(mqdes); CLASS(fd, f)(mqdes);
if (unlikely(!fd_file(f))) { if (fd_empty(f))
ret = -EBADF; return -EBADF;
goto out;
}
inode = file_inode(fd_file(f)); inode = file_inode(fd_file(f));
if (unlikely(fd_file(f)->f_op != &mqueue_file_operations)) { if (unlikely(fd_file(f)->f_op != &mqueue_file_operations))
ret = -EBADF; return -EBADF;
goto out_fput;
}
info = MQUEUE_I(inode); info = MQUEUE_I(inode);
audit_file(fd_file(f)); audit_file(fd_file(f));
if (unlikely(!(fd_file(f)->f_mode & FMODE_WRITE))) { if (unlikely(!(fd_file(f)->f_mode & FMODE_WRITE)))
ret = -EBADF; return -EBADF;
goto out_fput;
}
if (unlikely(msg_len > info->attr.mq_msgsize)) { if (unlikely(msg_len > info->attr.mq_msgsize))
ret = -EMSGSIZE; return -EMSGSIZE;
goto out_fput;
}
/* First try to allocate memory, before doing anything with /* First try to allocate memory, before doing anything with
* existing queues. */ * existing queues. */
msg_ptr = load_msg(u_msg_ptr, msg_len); msg_ptr = load_msg(u_msg_ptr, msg_len);
if (IS_ERR(msg_ptr)) { if (IS_ERR(msg_ptr))
ret = PTR_ERR(msg_ptr); return PTR_ERR(msg_ptr);
goto out_fput;
}
msg_ptr->m_ts = msg_len; msg_ptr->m_ts = msg_len;
msg_ptr->m_type = msg_prio; msg_ptr->m_type = msg_prio;
@ -1172,9 +1161,6 @@ out_unlock:
out_free: out_free:
if (ret) if (ret)
free_msg(msg_ptr); free_msg(msg_ptr);
out_fput:
fdput(f);
out:
return ret; return ret;
} }
@ -1184,7 +1170,6 @@ static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
{ {
ssize_t ret; ssize_t ret;
struct msg_msg *msg_ptr; struct msg_msg *msg_ptr;
struct fd f;
struct inode *inode; struct inode *inode;
struct mqueue_inode_info *info; struct mqueue_inode_info *info;
struct ext_wait_queue wait; struct ext_wait_queue wait;
@ -1198,30 +1183,22 @@ static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
audit_mq_sendrecv(mqdes, msg_len, 0, ts); audit_mq_sendrecv(mqdes, msg_len, 0, ts);
f = fdget(mqdes); CLASS(fd, f)(mqdes);
if (unlikely(!fd_file(f))) { if (fd_empty(f))
ret = -EBADF; return -EBADF;
goto out;
}
inode = file_inode(fd_file(f)); inode = file_inode(fd_file(f));
if (unlikely(fd_file(f)->f_op != &mqueue_file_operations)) { if (unlikely(fd_file(f)->f_op != &mqueue_file_operations))
ret = -EBADF; return -EBADF;
goto out_fput;
}
info = MQUEUE_I(inode); info = MQUEUE_I(inode);
audit_file(fd_file(f)); audit_file(fd_file(f));
if (unlikely(!(fd_file(f)->f_mode & FMODE_READ))) { if (unlikely(!(fd_file(f)->f_mode & FMODE_READ)))
ret = -EBADF; return -EBADF;
goto out_fput;
}
/* checks if buffer is big enough */ /* checks if buffer is big enough */
if (unlikely(msg_len < info->attr.mq_msgsize)) { if (unlikely(msg_len < info->attr.mq_msgsize))
ret = -EMSGSIZE; return -EMSGSIZE;
goto out_fput;
}
/* /*
* msg_insert really wants us to have a valid, spare node struct so * msg_insert really wants us to have a valid, spare node struct so
@ -1275,9 +1252,6 @@ static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
} }
free_msg(msg_ptr); free_msg(msg_ptr);
} }
out_fput:
fdput(f);
out:
return ret; return ret;
} }
@ -1437,21 +1411,18 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
static int do_mq_getsetattr(int mqdes, struct mq_attr *new, struct mq_attr *old) static int do_mq_getsetattr(int mqdes, struct mq_attr *new, struct mq_attr *old)
{ {
struct fd f;
struct inode *inode; struct inode *inode;
struct mqueue_inode_info *info; struct mqueue_inode_info *info;
if (new && (new->mq_flags & (~O_NONBLOCK))) if (new && (new->mq_flags & (~O_NONBLOCK)))
return -EINVAL; return -EINVAL;
f = fdget(mqdes); CLASS(fd, f)(mqdes);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
if (unlikely(fd_file(f)->f_op != &mqueue_file_operations)) { if (unlikely(fd_file(f)->f_op != &mqueue_file_operations))
fdput(f);
return -EBADF; return -EBADF;
}
inode = file_inode(fd_file(f)); inode = file_inode(fd_file(f));
info = MQUEUE_I(inode); info = MQUEUE_I(inode);
@ -1475,7 +1446,6 @@ static int do_mq_getsetattr(int mqdes, struct mq_attr *new, struct mq_attr *old)
} }
spin_unlock(&info->lock); spin_unlock(&info->lock);
fdput(f);
return 0; return 0;
} }

View File

@ -3219,10 +3219,7 @@ static int idempotent_init_module(struct file *f, const char __user * uargs, int
SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
{ {
int err; int err = may_init_module();
struct fd f;
err = may_init_module();
if (err) if (err)
return err; return err;
@ -3233,12 +3230,10 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
|MODULE_INIT_COMPRESSED_FILE)) |MODULE_INIT_COMPRESSED_FILE))
return -EINVAL; return -EINVAL;
f = fdget(fd); CLASS(fd, f)(fd);
if (fd_empty(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
err = idempotent_init_module(fd_file(f), uargs, flags); return idempotent_init_module(fd_file(f), uargs, flags);
fdput(f);
return err;
} }
/* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */ /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */

View File

@ -744,23 +744,18 @@ SYSCALL_DEFINE3(pidfd_getfd, int, pidfd, int, fd,
unsigned int, flags) unsigned int, flags)
{ {
struct pid *pid; struct pid *pid;
struct fd f;
int ret;
/* flags is currently unused - make sure it's unset */ /* flags is currently unused - make sure it's unset */
if (flags) if (flags)
return -EINVAL; return -EINVAL;
f = fdget(pidfd); CLASS(fd, f)(pidfd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
pid = pidfd_pid(fd_file(f)); pid = pidfd_pid(fd_file(f));
if (IS_ERR(pid)) if (IS_ERR(pid))
ret = PTR_ERR(pid); return PTR_ERR(pid);
else
ret = pidfd_getfd(pid, fd);
fdput(f); return pidfd_getfd(pid, fd);
return ret;
} }

View File

@ -3908,7 +3908,6 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
siginfo_t __user *, info, unsigned int, flags) siginfo_t __user *, info, unsigned int, flags)
{ {
int ret; int ret;
struct fd f;
struct pid *pid; struct pid *pid;
kernel_siginfo_t kinfo; kernel_siginfo_t kinfo;
enum pid_type type; enum pid_type type;
@ -3921,20 +3920,17 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
if (hweight32(flags & PIDFD_SEND_SIGNAL_FLAGS) > 1) if (hweight32(flags & PIDFD_SEND_SIGNAL_FLAGS) > 1)
return -EINVAL; return -EINVAL;
f = fdget(pidfd); CLASS(fd, f)(pidfd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
/* Is this a pidfd? */ /* Is this a pidfd? */
pid = pidfd_to_pid(fd_file(f)); pid = pidfd_to_pid(fd_file(f));
if (IS_ERR(pid)) { if (IS_ERR(pid))
ret = PTR_ERR(pid); return PTR_ERR(pid);
goto err;
}
ret = -EINVAL;
if (!access_pidfd_pidns(pid)) if (!access_pidfd_pidns(pid))
goto err; return -EINVAL;
switch (flags) { switch (flags) {
case 0: case 0:
@ -3958,28 +3954,23 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig,
if (info) { if (info) {
ret = copy_siginfo_from_user_any(&kinfo, info); ret = copy_siginfo_from_user_any(&kinfo, info);
if (unlikely(ret)) if (unlikely(ret))
goto err; return ret;
ret = -EINVAL;
if (unlikely(sig != kinfo.si_signo)) if (unlikely(sig != kinfo.si_signo))
goto err; return -EINVAL;
/* Only allow sending arbitrary signals to yourself. */ /* Only allow sending arbitrary signals to yourself. */
ret = -EPERM;
if ((task_pid(current) != pid || type > PIDTYPE_TGID) && if ((task_pid(current) != pid || type > PIDTYPE_TGID) &&
(kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL)) (kinfo.si_code >= 0 || kinfo.si_code == SI_TKILL))
goto err; return -EPERM;
} else { } else {
prepare_kill_siginfo(sig, &kinfo, type); prepare_kill_siginfo(sig, &kinfo, type);
} }
if (type == PIDTYPE_PGID) if (type == PIDTYPE_PGID)
ret = kill_pgrp_info(sig, &kinfo, pid); return kill_pgrp_info(sig, &kinfo, pid);
else else
ret = kill_pid_info_type(sig, &kinfo, pid, type); return kill_pid_info_type(sig, &kinfo, pid, type);
err:
fdput(f);
return ret;
} }
static int static int

View File

@ -411,15 +411,14 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
struct nlattr *na; struct nlattr *na;
size_t size; size_t size;
u32 fd; u32 fd;
struct fd f;
na = info->attrs[CGROUPSTATS_CMD_ATTR_FD]; na = info->attrs[CGROUPSTATS_CMD_ATTR_FD];
if (!na) if (!na)
return -EINVAL; return -EINVAL;
fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]);
f = fdget(fd); CLASS(fd, f)(fd);
if (!fd_file(f)) if (fd_empty(f))
return 0; return 0;
size = nla_total_size(sizeof(struct cgroupstats)); size = nla_total_size(sizeof(struct cgroupstats));
@ -427,14 +426,13 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb, rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb,
size); size);
if (rc < 0) if (rc < 0)
goto err; return rc;
na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS, na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS,
sizeof(struct cgroupstats)); sizeof(struct cgroupstats));
if (na == NULL) { if (na == NULL) {
nlmsg_free(rep_skb); nlmsg_free(rep_skb);
rc = -EMSGSIZE; return -EMSGSIZE;
goto err;
} }
stats = nla_data(na); stats = nla_data(na);
@ -443,14 +441,10 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
rc = cgroupstats_build(stats, fd_file(f)->f_path.dentry); rc = cgroupstats_build(stats, fd_file(f)->f_path.dentry);
if (rc < 0) { if (rc < 0) {
nlmsg_free(rep_skb); nlmsg_free(rep_skb);
goto err; return rc;
} }
rc = send_reply(rep_skb, info); return send_reply(rep_skb, info);
err:
fdput(f);
return rc;
} }
static int cmd_attr_register_cpumask(struct genl_info *info) static int cmd_attr_register_cpumask(struct genl_info *info)

View File

@ -1062,19 +1062,16 @@ out:
*/ */
void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) void ima_kexec_cmdline(int kernel_fd, const void *buf, int size)
{ {
struct fd f;
if (!buf || !size) if (!buf || !size)
return; return;
f = fdget(kernel_fd); CLASS(fd, f)(kernel_fd);
if (!fd_file(f)) if (fd_empty(f))
return; return;
process_buffer_measurement(file_mnt_idmap(fd_file(f)), file_inode(fd_file(f)), process_buffer_measurement(file_mnt_idmap(fd_file(f)), file_inode(fd_file(f)),
buf, size, "kexec-cmdline", KEXEC_CMDLINE, 0, buf, size, "kexec-cmdline", KEXEC_CMDLINE, 0,
NULL, false, NULL, 0); NULL, false, NULL, 0);
fdput(f);
} }
/** /**

View File

@ -283,7 +283,6 @@ enum loadpin_securityfs_interface_index {
static int read_trusted_verity_root_digests(unsigned int fd) static int read_trusted_verity_root_digests(unsigned int fd)
{ {
struct fd f;
void *data; void *data;
int rc; int rc;
char *p, *d; char *p, *d;
@ -295,8 +294,8 @@ static int read_trusted_verity_root_digests(unsigned int fd)
if (!list_empty(&dm_verity_loadpin_trusted_root_digests)) if (!list_empty(&dm_verity_loadpin_trusted_root_digests))
return -EPERM; return -EPERM;
f = fdget(fd); CLASS(fd, f)(fd);
if (!fd_file(f)) if (fd_empty(f))
return -EINVAL; return -EINVAL;
data = kzalloc(SZ_4K, GFP_KERNEL); data = kzalloc(SZ_4K, GFP_KERNEL);
@ -359,7 +358,6 @@ static int read_trusted_verity_root_digests(unsigned int fd)
} }
kfree(data); kfree(data);
fdput(f);
return 0; return 0;
@ -379,8 +377,6 @@ err:
/* disallow further attempts after reading a corrupt/invalid file */ /* disallow further attempts after reading a corrupt/invalid file */
deny_reading_verity_digests = true; deny_reading_verity_digests = true;
fdput(f);
return rc; return rc;
} }

View File

@ -229,14 +229,13 @@ static int kvm_vfio_file_set_spapr_tce(struct kvm_device *dev,
struct kvm_vfio_spapr_tce param; struct kvm_vfio_spapr_tce param;
struct kvm_vfio *kv = dev->private; struct kvm_vfio *kv = dev->private;
struct kvm_vfio_file *kvf; struct kvm_vfio_file *kvf;
struct fd f;
int ret; int ret;
if (copy_from_user(&param, arg, sizeof(struct kvm_vfio_spapr_tce))) if (copy_from_user(&param, arg, sizeof(struct kvm_vfio_spapr_tce)))
return -EFAULT; return -EFAULT;
f = fdget(param.groupfd); CLASS(fd, f)(param.groupfd);
if (!fd_file(f)) if (fd_empty(f))
return -EBADF; return -EBADF;
ret = -ENOENT; ret = -ENOENT;
@ -262,7 +261,6 @@ static int kvm_vfio_file_set_spapr_tce(struct kvm_device *dev,
err_fdput: err_fdput:
mutex_unlock(&kv->lock); mutex_unlock(&kv->lock);
fdput(f);
return ret; return ret;
} }
#endif #endif