Commit 63ff8223 authored by Jens Axboe's avatar Jens Axboe

io_uring: don't use 'fd' for openat/openat2/statx

We currently make some guesses as when to open this fd, but in reality
we have no business (or need) to do so at all. In fact, it makes certain
things fail, like O_PATH.

Remove the fd lookup from these opcodes, we're just passing the 'fd' to
generic helpers anyway. With that, we can also remove the special casing
of fd values in io_req_needs_file(), and the 'fd_non_neg' check that
we have. And we can ensure that we only read sqe->fd once.

This fixes O_PATH usage with openat/openat2, and ditto statx path side
oddities.

Cc: stable@vger.kernel.org: # v5.6
Reported-by: default avatarMax Kellermann <mk@cm4all.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 90da2e3f
...@@ -680,8 +680,6 @@ struct io_op_def { ...@@ -680,8 +680,6 @@ struct io_op_def {
unsigned needs_mm : 1; unsigned needs_mm : 1;
/* needs req->file assigned */ /* needs req->file assigned */
unsigned needs_file : 1; unsigned needs_file : 1;
/* needs req->file assigned IFF fd is >= 0 */
unsigned fd_non_neg : 1;
/* hash wq insertion if file is a regular file */ /* hash wq insertion if file is a regular file */
unsigned hash_reg_file : 1; unsigned hash_reg_file : 1;
/* unbound wq insertion if file is a non-regular file */ /* unbound wq insertion if file is a non-regular file */
...@@ -784,8 +782,6 @@ static const struct io_op_def io_op_defs[] = { ...@@ -784,8 +782,6 @@ static const struct io_op_def io_op_defs[] = {
.needs_file = 1, .needs_file = 1,
}, },
[IORING_OP_OPENAT] = { [IORING_OP_OPENAT] = {
.needs_file = 1,
.fd_non_neg = 1,
.file_table = 1, .file_table = 1,
.needs_fs = 1, .needs_fs = 1,
}, },
...@@ -799,8 +795,6 @@ static const struct io_op_def io_op_defs[] = { ...@@ -799,8 +795,6 @@ static const struct io_op_def io_op_defs[] = {
}, },
[IORING_OP_STATX] = { [IORING_OP_STATX] = {
.needs_mm = 1, .needs_mm = 1,
.needs_file = 1,
.fd_non_neg = 1,
.needs_fs = 1, .needs_fs = 1,
.file_table = 1, .file_table = 1,
}, },
...@@ -837,8 +831,6 @@ static const struct io_op_def io_op_defs[] = { ...@@ -837,8 +831,6 @@ static const struct io_op_def io_op_defs[] = {
.buffer_select = 1, .buffer_select = 1,
}, },
[IORING_OP_OPENAT2] = { [IORING_OP_OPENAT2] = {
.needs_file = 1,
.fd_non_neg = 1,
.file_table = 1, .file_table = 1,
.needs_fs = 1, .needs_fs = 1,
}, },
...@@ -5368,15 +5360,6 @@ static void io_wq_submit_work(struct io_wq_work **workptr) ...@@ -5368,15 +5360,6 @@ static void io_wq_submit_work(struct io_wq_work **workptr)
io_steal_work(req, workptr); io_steal_work(req, workptr);
} }
static int io_req_needs_file(struct io_kiocb *req, int fd)
{
if (!io_op_defs[req->opcode].needs_file)
return 0;
if ((fd == -1 || fd == AT_FDCWD) && io_op_defs[req->opcode].fd_non_neg)
return 0;
return 1;
}
static inline struct file *io_file_from_index(struct io_ring_ctx *ctx, static inline struct file *io_file_from_index(struct io_ring_ctx *ctx,
int index) int index)
{ {
...@@ -5414,14 +5397,11 @@ static int io_file_get(struct io_submit_state *state, struct io_kiocb *req, ...@@ -5414,14 +5397,11 @@ static int io_file_get(struct io_submit_state *state, struct io_kiocb *req,
} }
static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req, static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req,
int fd, unsigned int flags) int fd)
{ {
bool fixed; bool fixed;
if (!io_req_needs_file(req, fd)) fixed = (req->flags & REQ_F_FIXED_FILE) != 0;
return 0;
fixed = (flags & IOSQE_FIXED_FILE);
if (unlikely(!fixed && req->needs_fixed_file)) if (unlikely(!fixed && req->needs_fixed_file))
return -EBADF; return -EBADF;
...@@ -5798,7 +5778,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, ...@@ -5798,7 +5778,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
struct io_submit_state *state, bool async) struct io_submit_state *state, bool async)
{ {
unsigned int sqe_flags; unsigned int sqe_flags;
int id, fd; int id;
/* /*
* All io need record the previous position, if LINK vs DARIN, * All io need record the previous position, if LINK vs DARIN,
...@@ -5850,8 +5830,10 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, ...@@ -5850,8 +5830,10 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
IOSQE_ASYNC | IOSQE_FIXED_FILE | IOSQE_ASYNC | IOSQE_FIXED_FILE |
IOSQE_BUFFER_SELECT | IOSQE_IO_LINK); IOSQE_BUFFER_SELECT | IOSQE_IO_LINK);
fd = READ_ONCE(sqe->fd); if (!io_op_defs[req->opcode].needs_file)
return io_req_set_file(state, req, fd, sqe_flags); return 0;
return io_req_set_file(state, req, READ_ONCE(sqe->fd));
} }
static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
......
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