]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
io_uring: always allow drain/link/hardlink/async sqe flags
authorDaniele Albano <d.albano@gmail.com>
Sat, 18 Jul 2020 20:15:16 +0000 (14:15 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Aug 2020 07:58:48 +0000 (09:58 +0200)
[ Upstream commit 61710e437f2807e26a3402543bdbb7217a9c8620 ]

We currently filter these for timeout_remove/async_cancel/files_update,
but we only should be filtering for fixed file and buffer select. This
also causes a second read of sqe->flags, which isn't needed.

Just check req->flags for the relevant bits. This then allows these
commands to be used in links, for example, like everything else.

Signed-off-by: Daniele Albano <d.albano@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/io_uring.c

index d0d3efaaa4d4f9c684ff60bac554117c86a930f4..4e09af1d5d22393f53e7f436145b944e1b05e3ea 100644 (file)
@@ -4808,7 +4808,9 @@ static int io_timeout_remove_prep(struct io_kiocb *req,
 {
        if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
                return -EINVAL;
-       if (sqe->flags || sqe->ioprio || sqe->buf_index || sqe->len)
+       if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT)))
+               return -EINVAL;
+       if (sqe->ioprio || sqe->buf_index || sqe->len)
                return -EINVAL;
 
        req->timeout.addr = READ_ONCE(sqe->addr);
@@ -5014,8 +5016,9 @@ static int io_async_cancel_prep(struct io_kiocb *req,
 {
        if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
                return -EINVAL;
-       if (sqe->flags || sqe->ioprio || sqe->off || sqe->len ||
-           sqe->cancel_flags)
+       if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT)))
+               return -EINVAL;
+       if (sqe->ioprio || sqe->off || sqe->len || sqe->cancel_flags)
                return -EINVAL;
 
        req->cancel.addr = READ_ONCE(sqe->addr);
@@ -5033,7 +5036,9 @@ static int io_async_cancel(struct io_kiocb *req)
 static int io_files_update_prep(struct io_kiocb *req,
                                const struct io_uring_sqe *sqe)
 {
-       if (sqe->flags || sqe->ioprio || sqe->rw_flags)
+       if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT)))
+               return -EINVAL;
+       if (sqe->ioprio || sqe->rw_flags)
                return -EINVAL;
 
        req->files_update.offset = READ_ONCE(sqe->off);