mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 04:04:26 +08:00
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:
parent
6348be02ee
commit
8152f82010
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
fs/fsopen.c
19
fs/fsopen.c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
fs/locks.c
15
fs/locks.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
fs/open.c
12
fs/open.c
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
45
fs/splice.c
45
fs/splice.c
@ -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);
|
||||||
}
|
}
|
||||||
|
11
fs/utimes.c
11
fs/utimes.c
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
76
ipc/mqueue.c
76
ipc/mqueue.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 !!! */
|
||||||
|
13
kernel/pid.c
13
kernel/pid.c
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(¶m, arg, sizeof(struct kvm_vfio_spapr_tce)))
|
if (copy_from_user(¶m, 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
|
||||||
|
Loading…
Reference in New Issue
Block a user