OSDN Git Service

io_uring: support using a registered personality for commands
authorJens Axboe <axboe@kernel.dk>
Tue, 28 Jan 2020 17:15:23 +0000 (10:15 -0700)
committerJens Axboe <axboe@kernel.dk>
Wed, 29 Jan 2020 00:45:31 +0000 (17:45 -0700)
For personalities previously registered via IORING_REGISTER_PERSONALITY,
allow any command to select them. This is done through setting
sqe->personality to the id returned from registration, and then flagging
sqe->flags with IOSQE_PERSONALITY.

Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c
include/uapi/linux/io_uring.h

index d74567f..8bcf053 100644 (file)
@@ -4626,9 +4626,10 @@ static inline void io_queue_link_head(struct io_kiocb *req)
 static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                          struct io_submit_state *state, struct io_kiocb **link)
 {
+       const struct cred *old_creds = NULL;
        struct io_ring_ctx *ctx = req->ctx;
        unsigned int sqe_flags;
-       int ret;
+       int ret, id;
 
        sqe_flags = READ_ONCE(sqe->flags);
 
@@ -4637,6 +4638,19 @@ static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                ret = -EINVAL;
                goto err_req;
        }
+
+       id = READ_ONCE(sqe->personality);
+       if (id) {
+               const struct cred *personality_creds;
+
+               personality_creds = idr_find(&ctx->personality_idr, id);
+               if (unlikely(!personality_creds)) {
+                       ret = -EINVAL;
+                       goto err_req;
+               }
+               old_creds = override_creds(personality_creds);
+       }
+
        /* same numerical values with corresponding REQ_F_*, safe to copy */
        req->flags |= sqe_flags & (IOSQE_IO_DRAIN|IOSQE_IO_HARDLINK|
                                        IOSQE_ASYNC);
@@ -4646,6 +4660,8 @@ static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
 err_req:
                io_cqring_add_event(req, ret);
                io_double_put_req(req);
+               if (old_creds)
+                       revert_creds(old_creds);
                return false;
        }
 
@@ -4706,6 +4722,8 @@ err_req:
                }
        }
 
+       if (old_creds)
+               revert_creds(old_creds);
        return true;
 }
 
index b4ccf31..98105ff 100644 (file)
@@ -40,7 +40,12 @@ struct io_uring_sqe {
        };
        __u64   user_data;      /* data to be passed back at completion time */
        union {
-               __u16   buf_index;      /* index into fixed buffers, if used */
+               struct {
+                       /* index into fixed buffers, if used */
+                       __u16   buf_index;
+                       /* personality to use, if used */
+                       __u16   personality;
+               };
                __u64   __pad2[3];
        };
 };