Commit 9e3aa61a authored by Jens Axboe's avatar Jens Axboe

io_uring: ensure we return -EINVAL on unknown opcode

If we submit an unknown opcode and have fd == -1, io_op_needs_file()
will return true as we default to needing a file. Then when we go and
assign the file, we find the 'fd' invalid and return -EBADF. We really
should be returning -EINVAL for that case, as we normally do for
unsupported opcodes.

Change io_op_needs_file() to have the following return values:

0   - does not need a file
1   - does need a file
< 0 - error value

and use this to pass back the right value for this invalid case.
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 10d59345
...@@ -3062,7 +3062,12 @@ static void io_wq_submit_work(struct io_wq_work **workptr) ...@@ -3062,7 +3062,12 @@ static void io_wq_submit_work(struct io_wq_work **workptr)
} }
} }
static bool io_op_needs_file(const struct io_uring_sqe *sqe) static bool io_req_op_valid(int op)
{
return op >= IORING_OP_NOP && op < IORING_OP_LAST;
}
static int io_op_needs_file(const struct io_uring_sqe *sqe)
{ {
int op = READ_ONCE(sqe->opcode); int op = READ_ONCE(sqe->opcode);
...@@ -3073,9 +3078,11 @@ static bool io_op_needs_file(const struct io_uring_sqe *sqe) ...@@ -3073,9 +3078,11 @@ static bool io_op_needs_file(const struct io_uring_sqe *sqe)
case IORING_OP_TIMEOUT_REMOVE: case IORING_OP_TIMEOUT_REMOVE:
case IORING_OP_ASYNC_CANCEL: case IORING_OP_ASYNC_CANCEL:
case IORING_OP_LINK_TIMEOUT: case IORING_OP_LINK_TIMEOUT:
return false; return 0;
default: default:
return true; if (io_req_op_valid(op))
return 1;
return -EINVAL;
} }
} }
...@@ -3092,7 +3099,7 @@ static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req) ...@@ -3092,7 +3099,7 @@ static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req)
{ {
struct io_ring_ctx *ctx = req->ctx; struct io_ring_ctx *ctx = req->ctx;
unsigned flags; unsigned flags;
int fd; int fd, ret;
flags = READ_ONCE(req->sqe->flags); flags = READ_ONCE(req->sqe->flags);
fd = READ_ONCE(req->sqe->fd); fd = READ_ONCE(req->sqe->fd);
...@@ -3100,8 +3107,9 @@ static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req) ...@@ -3100,8 +3107,9 @@ static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req)
if (flags & IOSQE_IO_DRAIN) if (flags & IOSQE_IO_DRAIN)
req->flags |= REQ_F_IO_DRAIN; req->flags |= REQ_F_IO_DRAIN;
if (!io_op_needs_file(req->sqe)) ret = io_op_needs_file(req->sqe);
return 0; if (ret <= 0)
return ret;
if (flags & IOSQE_FIXED_FILE) { if (flags & IOSQE_FIXED_FILE) {
if (unlikely(!ctx->file_table || if (unlikely(!ctx->file_table ||
...@@ -3312,7 +3320,6 @@ static inline void io_queue_link_head(struct io_kiocb *req) ...@@ -3312,7 +3320,6 @@ static inline void io_queue_link_head(struct io_kiocb *req)
io_queue_sqe(req); io_queue_sqe(req);
} }
#define SQE_VALID_FLAGS (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK| \ #define SQE_VALID_FLAGS (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK| \
IOSQE_IO_HARDLINK) IOSQE_IO_HARDLINK)
......
...@@ -58,23 +58,28 @@ struct io_uring_sqe { ...@@ -58,23 +58,28 @@ struct io_uring_sqe {
#define IORING_SETUP_SQ_AFF (1U << 2) /* sq_thread_cpu is valid */ #define IORING_SETUP_SQ_AFF (1U << 2) /* sq_thread_cpu is valid */
#define IORING_SETUP_CQSIZE (1U << 3) /* app defines CQ size */ #define IORING_SETUP_CQSIZE (1U << 3) /* app defines CQ size */
#define IORING_OP_NOP 0 enum {
#define IORING_OP_READV 1 IORING_OP_NOP,
#define IORING_OP_WRITEV 2 IORING_OP_READV,
#define IORING_OP_FSYNC 3 IORING_OP_WRITEV,
#define IORING_OP_READ_FIXED 4 IORING_OP_FSYNC,
#define IORING_OP_WRITE_FIXED 5 IORING_OP_READ_FIXED,
#define IORING_OP_POLL_ADD 6 IORING_OP_WRITE_FIXED,
#define IORING_OP_POLL_REMOVE 7 IORING_OP_POLL_ADD,
#define IORING_OP_SYNC_FILE_RANGE 8 IORING_OP_POLL_REMOVE,
#define IORING_OP_SENDMSG 9 IORING_OP_SYNC_FILE_RANGE,
#define IORING_OP_RECVMSG 10 IORING_OP_SENDMSG,
#define IORING_OP_TIMEOUT 11 IORING_OP_RECVMSG,
#define IORING_OP_TIMEOUT_REMOVE 12 IORING_OP_TIMEOUT,
#define IORING_OP_ACCEPT 13 IORING_OP_TIMEOUT_REMOVE,
#define IORING_OP_ASYNC_CANCEL 14 IORING_OP_ACCEPT,
#define IORING_OP_LINK_TIMEOUT 15 IORING_OP_ASYNC_CANCEL,
#define IORING_OP_CONNECT 16 IORING_OP_LINK_TIMEOUT,
IORING_OP_CONNECT,
/* this goes last, obviously */
IORING_OP_LAST,
};
/* /*
* sqe->fsync_flags * sqe->fsync_flags
......
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