diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-03-24 14:01:01 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-03-24 14:01:01 -0700 |
commit | e344eb7be2a25c66a8bac5d4388f1a4583450a72 (patch) | |
tree | 0742287b58bd6e02d4cf1a9b2f129c6dbd1312ab | |
parent | fd3d06ff5f4fa23f32bdb7f4d9f308503801d9e0 (diff) | |
parent | 02a4d923e4400a36d340ea12d8058f69ebf3a383 (diff) |
Merge tag 'io_uring-6.3-2023-03-24' of git://git.kernel.dk/linux
Pull io_uring fixes from Jens Axboe:
- Fix an issue with repeated -ECONNREFUSED on a socket (me)
- Fix a NULL pointer deference due to a stale lookup cache for
allocating direct descriptors (Savino)
* tag 'io_uring-6.3-2023-03-24' of git://git.kernel.dk/linux:
io_uring/rsrc: fix null-ptr-deref in io_file_bitmap_get()
io_uring/net: avoid sending -ECONNABORTED on repeated connection requests
-rw-r--r-- | io_uring/filetable.c | 3 | ||||
-rw-r--r-- | io_uring/net.c | 25 | ||||
-rw-r--r-- | io_uring/rsrc.c | 1 |
3 files changed, 20 insertions, 9 deletions
diff --git a/io_uring/filetable.c b/io_uring/filetable.c index 68dfc6936aa7..b80614e7d605 100644 --- a/io_uring/filetable.c +++ b/io_uring/filetable.c @@ -19,6 +19,9 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx) unsigned long nr = ctx->file_alloc_end; int ret; + if (!table->bitmap) + return -ENFILE; + do { ret = find_next_zero_bit(table->bitmap, nr, table->alloc_hint); if (ret != nr) diff --git a/io_uring/net.c b/io_uring/net.c index b7f190ca528e..4040cf093318 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -47,6 +47,7 @@ struct io_connect { struct sockaddr __user *addr; int addr_len; bool in_progress; + bool seen_econnaborted; }; struct io_sr_msg { @@ -1424,7 +1425,7 @@ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); conn->addr_len = READ_ONCE(sqe->addr2); - conn->in_progress = false; + conn->in_progress = conn->seen_econnaborted = false; return 0; } @@ -1461,18 +1462,24 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags) ret = __sys_connect_file(req->file, &io->address, connect->addr_len, file_flags); - if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) { + if ((ret == -EAGAIN || ret == -EINPROGRESS || ret == -ECONNABORTED) + && force_nonblock) { if (ret == -EINPROGRESS) { connect->in_progress = true; - } else { - if (req_has_async_data(req)) - return -EAGAIN; - if (io_alloc_async_data(req)) { - ret = -ENOMEM; + return -EAGAIN; + } + if (ret == -ECONNABORTED) { + if (connect->seen_econnaborted) goto out; - } - memcpy(req->async_data, &__io, sizeof(__io)); + connect->seen_econnaborted = true; + } + if (req_has_async_data(req)) + return -EAGAIN; + if (io_alloc_async_data(req)) { + ret = -ENOMEM; + goto out; } + memcpy(req->async_data, &__io, sizeof(__io)); return -EAGAIN; } if (ret == -ERESTARTSYS) diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index e2bac9f89902..7a43aed8e395 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -794,6 +794,7 @@ void __io_sqe_files_unregister(struct io_ring_ctx *ctx) } #endif io_free_file_tables(&ctx->file_table); + io_file_table_set_alloc_range(ctx, 0, 0); io_rsrc_data_free(ctx->file_data); ctx->file_data = NULL; ctx->nr_user_files = 0; |