Commit 26578cda authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Jens Axboe

io_uring: add ->splice_fd_in checks

->splice_fd_in is used only by splice/tee, but no other request checks
it for validity. Add the check for most of request types excluding
reads/writes/sends/recvs, we don't want overhead for them and can leave
them be as is until the field is actually used.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/f44bc2acd6777d932de3d71a5692235b5b2b7397.1629451684.git.asml.silence@gmail.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 2c5d763c
...@@ -3511,7 +3511,7 @@ static int io_renameat_prep(struct io_kiocb *req, ...@@ -3511,7 +3511,7 @@ static int io_renameat_prep(struct io_kiocb *req,
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->buf_index) if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
if (unlikely(req->flags & REQ_F_FIXED_FILE)) if (unlikely(req->flags & REQ_F_FIXED_FILE))
return -EBADF; return -EBADF;
...@@ -3562,7 +3562,8 @@ static int io_unlinkat_prep(struct io_kiocb *req, ...@@ -3562,7 +3562,8 @@ static int io_unlinkat_prep(struct io_kiocb *req,
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->off || sqe->len || sqe->buf_index) if (sqe->ioprio || sqe->off || sqe->len || sqe->buf_index ||
sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
if (unlikely(req->flags & REQ_F_FIXED_FILE)) if (unlikely(req->flags & REQ_F_FIXED_FILE))
return -EBADF; return -EBADF;
...@@ -3608,8 +3609,8 @@ static int io_shutdown_prep(struct io_kiocb *req, ...@@ -3608,8 +3609,8 @@ static int io_shutdown_prep(struct io_kiocb *req,
#if defined(CONFIG_NET) #if defined(CONFIG_NET)
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->off || sqe->addr || sqe->rw_flags || if (unlikely(sqe->ioprio || sqe->off || sqe->addr || sqe->rw_flags ||
sqe->buf_index) sqe->buf_index || sqe->splice_fd_in))
return -EINVAL; return -EINVAL;
req->shutdown.how = READ_ONCE(sqe->len); req->shutdown.how = READ_ONCE(sqe->len);
...@@ -3757,7 +3758,8 @@ static int io_fsync_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ...@@ -3757,7 +3758,8 @@ static int io_fsync_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
if (unlikely(ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (unlikely(sqe->addr || sqe->ioprio || sqe->buf_index)) if (unlikely(sqe->addr || sqe->ioprio || sqe->buf_index ||
sqe->splice_fd_in))
return -EINVAL; return -EINVAL;
req->sync.flags = READ_ONCE(sqe->fsync_flags); req->sync.flags = READ_ONCE(sqe->fsync_flags);
...@@ -3790,7 +3792,8 @@ static int io_fsync(struct io_kiocb *req, unsigned int issue_flags) ...@@ -3790,7 +3792,8 @@ static int io_fsync(struct io_kiocb *req, unsigned int issue_flags)
static int io_fallocate_prep(struct io_kiocb *req, static int io_fallocate_prep(struct io_kiocb *req,
const struct io_uring_sqe *sqe) const struct io_uring_sqe *sqe)
{ {
if (sqe->ioprio || sqe->buf_index || sqe->rw_flags) if (sqe->ioprio || sqe->buf_index || sqe->rw_flags ||
sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
...@@ -3823,7 +3826,7 @@ static int __io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe ...@@ -3823,7 +3826,7 @@ static int __io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (unlikely(sqe->ioprio || sqe->buf_index)) if (unlikely(sqe->ioprio || sqe->buf_index || sqe->splice_fd_in))
return -EINVAL; return -EINVAL;
if (unlikely(req->flags & REQ_F_FIXED_FILE)) if (unlikely(req->flags & REQ_F_FIXED_FILE))
return -EBADF; return -EBADF;
...@@ -3942,7 +3945,8 @@ static int io_remove_buffers_prep(struct io_kiocb *req, ...@@ -3942,7 +3945,8 @@ static int io_remove_buffers_prep(struct io_kiocb *req,
struct io_provide_buf *p = &req->pbuf; struct io_provide_buf *p = &req->pbuf;
u64 tmp; u64 tmp;
if (sqe->ioprio || sqe->rw_flags || sqe->addr || sqe->len || sqe->off) if (sqe->ioprio || sqe->rw_flags || sqe->addr || sqe->len || sqe->off ||
sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
tmp = READ_ONCE(sqe->fd); tmp = READ_ONCE(sqe->fd);
...@@ -4013,7 +4017,7 @@ static int io_provide_buffers_prep(struct io_kiocb *req, ...@@ -4013,7 +4017,7 @@ static int io_provide_buffers_prep(struct io_kiocb *req,
struct io_provide_buf *p = &req->pbuf; struct io_provide_buf *p = &req->pbuf;
u64 tmp; u64 tmp;
if (sqe->ioprio || sqe->rw_flags) if (sqe->ioprio || sqe->rw_flags || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
tmp = READ_ONCE(sqe->fd); tmp = READ_ONCE(sqe->fd);
...@@ -4100,7 +4104,7 @@ static int io_epoll_ctl_prep(struct io_kiocb *req, ...@@ -4100,7 +4104,7 @@ static int io_epoll_ctl_prep(struct io_kiocb *req,
const struct io_uring_sqe *sqe) const struct io_uring_sqe *sqe)
{ {
#if defined(CONFIG_EPOLL) #if defined(CONFIG_EPOLL)
if (sqe->ioprio || sqe->buf_index) if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
...@@ -4146,7 +4150,7 @@ static int io_epoll_ctl(struct io_kiocb *req, unsigned int issue_flags) ...@@ -4146,7 +4150,7 @@ static int io_epoll_ctl(struct io_kiocb *req, unsigned int issue_flags)
static int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) static int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{ {
#if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU) #if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
if (sqe->ioprio || sqe->buf_index || sqe->off) if (sqe->ioprio || sqe->buf_index || sqe->off || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
...@@ -4181,7 +4185,7 @@ static int io_madvise(struct io_kiocb *req, unsigned int issue_flags) ...@@ -4181,7 +4185,7 @@ static int io_madvise(struct io_kiocb *req, unsigned int issue_flags)
static int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) static int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{ {
if (sqe->ioprio || sqe->buf_index || sqe->addr) if (sqe->ioprio || sqe->buf_index || sqe->addr || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
...@@ -4219,7 +4223,7 @@ static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ...@@ -4219,7 +4223,7 @@ static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{ {
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->buf_index) if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
if (req->flags & REQ_F_FIXED_FILE) if (req->flags & REQ_F_FIXED_FILE)
return -EBADF; return -EBADF;
...@@ -4255,7 +4259,7 @@ static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ...@@ -4255,7 +4259,7 @@ static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->off || sqe->addr || sqe->len || if (sqe->ioprio || sqe->off || sqe->addr || sqe->len ||
sqe->rw_flags || sqe->buf_index) sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
if (req->flags & REQ_F_FIXED_FILE) if (req->flags & REQ_F_FIXED_FILE)
return -EBADF; return -EBADF;
...@@ -4316,7 +4320,8 @@ static int io_sfr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ...@@ -4316,7 +4320,8 @@ static int io_sfr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
if (unlikely(ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (unlikely(sqe->addr || sqe->ioprio || sqe->buf_index)) if (unlikely(sqe->addr || sqe->ioprio || sqe->buf_index ||
sqe->splice_fd_in))
return -EINVAL; return -EINVAL;
req->sync.off = READ_ONCE(sqe->off); req->sync.off = READ_ONCE(sqe->off);
...@@ -4743,7 +4748,7 @@ static int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ...@@ -4743,7 +4748,7 @@ static int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->len || sqe->buf_index) if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));
...@@ -4791,7 +4796,8 @@ static int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ...@@ -4791,7 +4796,8 @@ static int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->rw_flags) if (sqe->ioprio || sqe->len || sqe->buf_index || sqe->rw_flags ||
sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));
...@@ -5387,7 +5393,7 @@ static int io_poll_update_prep(struct io_kiocb *req, ...@@ -5387,7 +5393,7 @@ static int io_poll_update_prep(struct io_kiocb *req,
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->buf_index) if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
flags = READ_ONCE(sqe->len); flags = READ_ONCE(sqe->len);
if (flags & ~(IORING_POLL_UPDATE_EVENTS | IORING_POLL_UPDATE_USER_DATA | if (flags & ~(IORING_POLL_UPDATE_EVENTS | IORING_POLL_UPDATE_USER_DATA |
...@@ -5626,7 +5632,7 @@ static int io_timeout_remove_prep(struct io_kiocb *req, ...@@ -5626,7 +5632,7 @@ static int io_timeout_remove_prep(struct io_kiocb *req,
return -EINVAL; return -EINVAL;
if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT)))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->buf_index || sqe->len) if (sqe->ioprio || sqe->buf_index || sqe->len || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
tr->addr = READ_ONCE(sqe->addr); tr->addr = READ_ONCE(sqe->addr);
...@@ -5687,7 +5693,8 @@ static int io_timeout_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, ...@@ -5687,7 +5693,8 @@ static int io_timeout_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe,
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->buf_index || sqe->len != 1) if (sqe->ioprio || sqe->buf_index || sqe->len != 1 ||
sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
if (off && is_timeout_link) if (off && is_timeout_link)
return -EINVAL; return -EINVAL;
...@@ -5843,7 +5850,8 @@ static int io_async_cancel_prep(struct io_kiocb *req, ...@@ -5843,7 +5850,8 @@ static int io_async_cancel_prep(struct io_kiocb *req,
return -EINVAL; return -EINVAL;
if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT)))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->off || sqe->len || sqe->cancel_flags) if (sqe->ioprio || sqe->off || sqe->len || sqe->cancel_flags ||
sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
req->cancel.addr = READ_ONCE(sqe->addr); req->cancel.addr = READ_ONCE(sqe->addr);
...@@ -5884,7 +5892,7 @@ static int io_rsrc_update_prep(struct io_kiocb *req, ...@@ -5884,7 +5892,7 @@ static int io_rsrc_update_prep(struct io_kiocb *req,
{ {
if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT)))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->rw_flags) if (sqe->ioprio || sqe->rw_flags || sqe->splice_fd_in)
return -EINVAL; return -EINVAL;
req->rsrc_update.offset = READ_ONCE(sqe->off); req->rsrc_update.offset = READ_ONCE(sqe->off);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment