|
80 | 80 | #include <linux/io_uring.h>
|
81 | 81 | #include <linux/audit.h>
|
82 | 82 | #include <linux/security.h>
|
83 |
| -#include <linux/xattr.h> |
84 | 83 |
|
85 | 84 | #define CREATE_TRACE_POINTS
|
86 | 85 | #include <trace/events/io_uring.h>
|
|
93 | 92 | #include "io_uring_types.h"
|
94 | 93 | #include "io_uring.h"
|
95 | 94 |
|
| 95 | +#include "xattr.h" |
| 96 | + |
96 | 97 | #define IORING_MAX_ENTRIES 32768
|
97 | 98 | #define IORING_MAX_CQ_ENTRIES (2 * IORING_MAX_ENTRIES)
|
98 | 99 | #define IORING_SQPOLL_CAP_ENTRIES_VALUE 8
|
@@ -529,12 +530,6 @@ struct io_async_rw {
|
529 | 530 | struct wait_page_queue wpq;
|
530 | 531 | };
|
531 | 532 |
|
532 |
| -struct io_xattr { |
533 |
| - struct file *file; |
534 |
| - struct xattr_ctx ctx; |
535 |
| - struct filename *filename; |
536 |
| -}; |
537 |
| - |
538 | 533 | struct async_poll {
|
539 | 534 | struct io_poll poll;
|
540 | 535 | struct io_poll *double_poll;
|
@@ -3904,245 +3899,6 @@ static void io_renameat_cleanup(struct io_kiocb *req)
|
3904 | 3899 | putname(ren->newpath);
|
3905 | 3900 | }
|
3906 | 3901 |
|
3907 |
| -static inline void io_xattr_cleanup(struct io_kiocb *req) |
3908 |
| -{ |
3909 |
| - struct io_xattr *ix = io_kiocb_to_cmd(req); |
3910 |
| - |
3911 |
| - if (ix->filename) |
3912 |
| - putname(ix->filename); |
3913 |
| - |
3914 |
| - kfree(ix->ctx.kname); |
3915 |
| - kvfree(ix->ctx.kvalue); |
3916 |
| -} |
3917 |
| - |
3918 |
| -static void io_xattr_finish(struct io_kiocb *req, int ret) |
3919 |
| -{ |
3920 |
| - req->flags &= ~REQ_F_NEED_CLEANUP; |
3921 |
| - |
3922 |
| - io_xattr_cleanup(req); |
3923 |
| - io_req_set_res(req, ret, 0); |
3924 |
| -} |
3925 |
| - |
3926 |
| -static int __io_getxattr_prep(struct io_kiocb *req, |
3927 |
| - const struct io_uring_sqe *sqe) |
3928 |
| -{ |
3929 |
| - struct io_xattr *ix = io_kiocb_to_cmd(req); |
3930 |
| - const char __user *name; |
3931 |
| - int ret; |
3932 |
| - |
3933 |
| - if (unlikely(req->flags & REQ_F_FIXED_FILE)) |
3934 |
| - return -EBADF; |
3935 |
| - |
3936 |
| - ix->filename = NULL; |
3937 |
| - ix->ctx.kvalue = NULL; |
3938 |
| - name = u64_to_user_ptr(READ_ONCE(sqe->addr)); |
3939 |
| - ix->ctx.cvalue = u64_to_user_ptr(READ_ONCE(sqe->addr2)); |
3940 |
| - ix->ctx.size = READ_ONCE(sqe->len); |
3941 |
| - ix->ctx.flags = READ_ONCE(sqe->xattr_flags); |
3942 |
| - |
3943 |
| - if (ix->ctx.flags) |
3944 |
| - return -EINVAL; |
3945 |
| - |
3946 |
| - ix->ctx.kname = kmalloc(sizeof(*ix->ctx.kname), GFP_KERNEL); |
3947 |
| - if (!ix->ctx.kname) |
3948 |
| - return -ENOMEM; |
3949 |
| - |
3950 |
| - ret = strncpy_from_user(ix->ctx.kname->name, name, |
3951 |
| - sizeof(ix->ctx.kname->name)); |
3952 |
| - if (!ret || ret == sizeof(ix->ctx.kname->name)) |
3953 |
| - ret = -ERANGE; |
3954 |
| - if (ret < 0) { |
3955 |
| - kfree(ix->ctx.kname); |
3956 |
| - return ret; |
3957 |
| - } |
3958 |
| - |
3959 |
| - req->flags |= REQ_F_NEED_CLEANUP; |
3960 |
| - return 0; |
3961 |
| -} |
3962 |
| - |
3963 |
| -static int io_fgetxattr_prep(struct io_kiocb *req, |
3964 |
| - const struct io_uring_sqe *sqe) |
3965 |
| -{ |
3966 |
| - return __io_getxattr_prep(req, sqe); |
3967 |
| -} |
3968 |
| - |
3969 |
| -static int io_getxattr_prep(struct io_kiocb *req, |
3970 |
| - const struct io_uring_sqe *sqe) |
3971 |
| -{ |
3972 |
| - struct io_xattr *ix = io_kiocb_to_cmd(req); |
3973 |
| - const char __user *path; |
3974 |
| - int ret; |
3975 |
| - |
3976 |
| - ret = __io_getxattr_prep(req, sqe); |
3977 |
| - if (ret) |
3978 |
| - return ret; |
3979 |
| - |
3980 |
| - path = u64_to_user_ptr(READ_ONCE(sqe->addr3)); |
3981 |
| - |
3982 |
| - ix->filename = getname_flags(path, LOOKUP_FOLLOW, NULL); |
3983 |
| - if (IS_ERR(ix->filename)) { |
3984 |
| - ret = PTR_ERR(ix->filename); |
3985 |
| - ix->filename = NULL; |
3986 |
| - } |
3987 |
| - |
3988 |
| - return ret; |
3989 |
| -} |
3990 |
| - |
3991 |
| -static int io_fgetxattr(struct io_kiocb *req, unsigned int issue_flags) |
3992 |
| -{ |
3993 |
| - struct io_xattr *ix = io_kiocb_to_cmd(req); |
3994 |
| - int ret; |
3995 |
| - |
3996 |
| - if (issue_flags & IO_URING_F_NONBLOCK) |
3997 |
| - return -EAGAIN; |
3998 |
| - |
3999 |
| - ret = do_getxattr(mnt_user_ns(req->file->f_path.mnt), |
4000 |
| - req->file->f_path.dentry, |
4001 |
| - &ix->ctx); |
4002 |
| - |
4003 |
| - io_xattr_finish(req, ret); |
4004 |
| - return IOU_OK; |
4005 |
| -} |
4006 |
| - |
4007 |
| -static int io_getxattr(struct io_kiocb *req, unsigned int issue_flags) |
4008 |
| -{ |
4009 |
| - struct io_xattr *ix = io_kiocb_to_cmd(req); |
4010 |
| - unsigned int lookup_flags = LOOKUP_FOLLOW; |
4011 |
| - struct path path; |
4012 |
| - int ret; |
4013 |
| - |
4014 |
| - if (issue_flags & IO_URING_F_NONBLOCK) |
4015 |
| - return -EAGAIN; |
4016 |
| - |
4017 |
| -retry: |
4018 |
| - ret = filename_lookup(AT_FDCWD, ix->filename, lookup_flags, &path, NULL); |
4019 |
| - if (!ret) { |
4020 |
| - ret = do_getxattr(mnt_user_ns(path.mnt), |
4021 |
| - path.dentry, |
4022 |
| - &ix->ctx); |
4023 |
| - |
4024 |
| - path_put(&path); |
4025 |
| - if (retry_estale(ret, lookup_flags)) { |
4026 |
| - lookup_flags |= LOOKUP_REVAL; |
4027 |
| - goto retry; |
4028 |
| - } |
4029 |
| - } |
4030 |
| - |
4031 |
| - io_xattr_finish(req, ret); |
4032 |
| - return IOU_OK; |
4033 |
| -} |
4034 |
| - |
4035 |
| -static int __io_setxattr_prep(struct io_kiocb *req, |
4036 |
| - const struct io_uring_sqe *sqe) |
4037 |
| -{ |
4038 |
| - struct io_xattr *ix = io_kiocb_to_cmd(req); |
4039 |
| - const char __user *name; |
4040 |
| - int ret; |
4041 |
| - |
4042 |
| - if (unlikely(req->flags & REQ_F_FIXED_FILE)) |
4043 |
| - return -EBADF; |
4044 |
| - |
4045 |
| - ix->filename = NULL; |
4046 |
| - name = u64_to_user_ptr(READ_ONCE(sqe->addr)); |
4047 |
| - ix->ctx.cvalue = u64_to_user_ptr(READ_ONCE(sqe->addr2)); |
4048 |
| - ix->ctx.kvalue = NULL; |
4049 |
| - ix->ctx.size = READ_ONCE(sqe->len); |
4050 |
| - ix->ctx.flags = READ_ONCE(sqe->xattr_flags); |
4051 |
| - |
4052 |
| - ix->ctx.kname = kmalloc(sizeof(*ix->ctx.kname), GFP_KERNEL); |
4053 |
| - if (!ix->ctx.kname) |
4054 |
| - return -ENOMEM; |
4055 |
| - |
4056 |
| - ret = setxattr_copy(name, &ix->ctx); |
4057 |
| - if (ret) { |
4058 |
| - kfree(ix->ctx.kname); |
4059 |
| - return ret; |
4060 |
| - } |
4061 |
| - |
4062 |
| - req->flags |= REQ_F_NEED_CLEANUP; |
4063 |
| - return 0; |
4064 |
| -} |
4065 |
| - |
4066 |
| -static int io_setxattr_prep(struct io_kiocb *req, |
4067 |
| - const struct io_uring_sqe *sqe) |
4068 |
| -{ |
4069 |
| - struct io_xattr *ix = io_kiocb_to_cmd(req); |
4070 |
| - const char __user *path; |
4071 |
| - int ret; |
4072 |
| - |
4073 |
| - ret = __io_setxattr_prep(req, sqe); |
4074 |
| - if (ret) |
4075 |
| - return ret; |
4076 |
| - |
4077 |
| - path = u64_to_user_ptr(READ_ONCE(sqe->addr3)); |
4078 |
| - |
4079 |
| - ix->filename = getname_flags(path, LOOKUP_FOLLOW, NULL); |
4080 |
| - if (IS_ERR(ix->filename)) { |
4081 |
| - ret = PTR_ERR(ix->filename); |
4082 |
| - ix->filename = NULL; |
4083 |
| - } |
4084 |
| - |
4085 |
| - return ret; |
4086 |
| -} |
4087 |
| - |
4088 |
| -static int io_fsetxattr_prep(struct io_kiocb *req, |
4089 |
| - const struct io_uring_sqe *sqe) |
4090 |
| -{ |
4091 |
| - return __io_setxattr_prep(req, sqe); |
4092 |
| -} |
4093 |
| - |
4094 |
| -static int __io_setxattr(struct io_kiocb *req, unsigned int issue_flags, |
4095 |
| - struct path *path) |
4096 |
| -{ |
4097 |
| - struct io_xattr *ix = io_kiocb_to_cmd(req); |
4098 |
| - int ret; |
4099 |
| - |
4100 |
| - ret = mnt_want_write(path->mnt); |
4101 |
| - if (!ret) { |
4102 |
| - ret = do_setxattr(mnt_user_ns(path->mnt), path->dentry, &ix->ctx); |
4103 |
| - mnt_drop_write(path->mnt); |
4104 |
| - } |
4105 |
| - |
4106 |
| - return ret; |
4107 |
| -} |
4108 |
| - |
4109 |
| -static int io_fsetxattr(struct io_kiocb *req, unsigned int issue_flags) |
4110 |
| -{ |
4111 |
| - int ret; |
4112 |
| - |
4113 |
| - if (issue_flags & IO_URING_F_NONBLOCK) |
4114 |
| - return -EAGAIN; |
4115 |
| - |
4116 |
| - ret = __io_setxattr(req, issue_flags, &req->file->f_path); |
4117 |
| - io_xattr_finish(req, ret); |
4118 |
| - return IOU_OK; |
4119 |
| -} |
4120 |
| - |
4121 |
| -static int io_setxattr(struct io_kiocb *req, unsigned int issue_flags) |
4122 |
| -{ |
4123 |
| - struct io_xattr *ix = io_kiocb_to_cmd(req); |
4124 |
| - unsigned int lookup_flags = LOOKUP_FOLLOW; |
4125 |
| - struct path path; |
4126 |
| - int ret; |
4127 |
| - |
4128 |
| - if (issue_flags & IO_URING_F_NONBLOCK) |
4129 |
| - return -EAGAIN; |
4130 |
| - |
4131 |
| -retry: |
4132 |
| - ret = filename_lookup(AT_FDCWD, ix->filename, lookup_flags, &path, NULL); |
4133 |
| - if (!ret) { |
4134 |
| - ret = __io_setxattr(req, issue_flags, &path); |
4135 |
| - path_put(&path); |
4136 |
| - if (retry_estale(ret, lookup_flags)) { |
4137 |
| - lookup_flags |= LOOKUP_REVAL; |
4138 |
| - goto retry; |
4139 |
| - } |
4140 |
| - } |
4141 |
| - |
4142 |
| - io_xattr_finish(req, ret); |
4143 |
| - return IOU_OK; |
4144 |
| -} |
4145 |
| - |
4146 | 3902 | static int io_unlinkat_prep(struct io_kiocb *req,
|
4147 | 3903 | const struct io_uring_sqe *sqe)
|
4148 | 3904 | {
|
|
0 commit comments