aboutsummaryrefslogtreecommitdiff
path: root/io_uring
AgeCommit message (Collapse)AuthorFilesLines
2 daysMerge tag 'io_uring-7.4-20261029' of ↵Linus Torvalds13-44/+169
git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux Pull io_uring fixes from Jens Axboe: - A batch of fixes from Chris: - Charge registered buffer arrays, rsrc nodes, tctx nodes and personalities to memcg, and free the XArray nodes a failed store leaves behind. - Clear bpf_ctx while submitting SQEs from a bpf-ops program, as the socket code otherwise skips both the capability check and lock_sock() for a setsockopt from the SQ. - Free the task context after an RCU grace period, closing a UAF when a foreign task frees the last request. - Stop io_ring_exit_work() from waiting on an SQPOLL thread held in get_signal(), and drop sqd->lock while the thread waits for in-flight requests, as either one could pin every iou_exit slot - io-wq fixes: - Don't create new workers once the exit has begun, which could leave an exiting worker in the thread group under exec - save the worker type before dropping its reference (KASAN UAF) - Defer io-wq enqueues from a foreign task to task_work, as an IOPOLL reap by another task could race io_wq_put_and_exit() - Keep the drain active when the deferred request being started is itself a drain request, and don't attach a new ring to an SQPOLL thread that is already canceling - Fix the multishot recv length limit accounting, and count cancelled timeouts in cq_timeouts so an armed off timeout doesn't fire early - Advance the buffer ring head when a pickup empties it, and keep the recvmsg buffer select length within MAX_RW_COUNT - Mask the socket type in the bpf filter population so SOCK_CLOEXEC or SOCK_NONBLOCK can't bypass a type filter, and enforce the per-task register restrictions for blind registration - Complete a non-blocking connect() that fails with -EAGAIN rather than retrying it through poll and io-wq, matching connect(2) - napi list traversal cleanup, and remove a useless min_not_zero() * tag 'io_uring-7.4-20261029' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: (21 commits) io_uring/sqpoll: don't attach to a thread that is canceling io_uring/net: fix multishot recv length limit accounting io_uring/timeout: count cancelled timeouts in cq_timeouts io_uring/napi: clean up list traversal with list_for_each_entry_safe() io_uring: defer foreign io-wq enqueues to task_work io_uring/io-wq: save worker type before dropping its reference io_uring/cancel: drop sqd->lock while SQPOLL waits io_uring/sqpoll: don't wait for the thread to exit io_uring: free the task context after a grace period io_uring/bpf-ops: clear bpf_ctx while submitting SQEs io_uring: free XArray nodes left by a failed store io_uring: charge tctx nodes and personalities io_uring/rsrc: charge buffer arrays and nodes to memcg io_uring/io-wq: no new workers once the exit has begun io_uring: keep the drain active when a deferred drain request is started io_uring/net: don't retry a non-blocking connect() that fails with -EAGAIN io_uring/register: enforce per-task restrictions in io_uring_register_blind() io_uring/net: mask socket type with SOCK_TYPE_MASK in io_socket_bpf_populate() io_uring/net: Remove useless min_not_zero() usage io_uring/net: keep recvmsg buffer select length within MAX_RW_COUNT ...
3 daysio_uring/sqpoll: don't attach to a thread that is cancelingJens Axboe1-1/+10
io_sq_offload_create() refuses to attach a ring to an SQPOLL thread that has already gone, by checking sqd->thread under sqd->lock. Since the thread drops the lock while io_uring_cancel_generic() waits for its requests, that check can run while the thread is on its way out and still see it. The new ring is then added to ctx_list, io_uring_setup() succeeds, the thread finishes canceling and exits without ever having looked at the ring, and io_uring_enter() fails with -EOWNERDEAD. Only a thread that exits on a fatal signal can be caught like this, as the stop bit is set once the last ring has let go of the sqd, when no fd is left to attach through. A fatal signal is group wide and attaching needs the same thread group, so the attacher is on its way out as well. Still, make the check see it: set the stop bit before canceling, whatever the reason for the exit, and test it when attaching. Reported-by: Karl Mehltretter <kmehltretter@gmail.com> Fixes: cb0306c52ffa ("io_uring/cancel: drop sqd->lock while SQPOLL waits") Signed-off-by: Jens Axboe <axboe@kernel.dk>
3 daysio_uring/net: fix multishot recv length limit accountingCheng Yongkang1-4/+7
io_recv_finish() debits sr->mshot_total_len with min_t(int, sel->val, sr->mshot_total_len). sel->val is the cumulative byte count of the request: on a bundle retry the receive path adds sr->done_io back to the return value, and the bundle branch in io_recv_finish() recovers the new bytes with this_ret = sel->val - sr->done_io. The debit therefore uses the wrong value after a bundle retry, and the int cast truncates a limit above INT_MAX. For an IORING_OP_RECV multishot request with optlen above INT_MAX, the limit becomes negative when cast to int, so the first completion debits the entire limit and ends the multishot with IORING_RECV_MSHOT_DONE while the socket still holds data that covers the limit. With 120 bytes queued, a 64-byte buffer and optlen 0x80000000, the first 64-byte CQE lacks IORING_CQE_F_MORE and 56 bytes remain unread; the same setup with optlen 0x7fffffff posts 64 and 56 bytes with F_MORE. After a bundle retry, the bytes already debited for the previous attempts are debited again, so the limit is exhausted early. With 1400 bytes queued, optlen 1000 and buffers of 600, 100, 100, 50, 50 and 200 bytes, the first attempt delivers 700 bytes and retries; the second delivers 200 more, but the debit accounts for 900 and finishes the request with a terminal 900-byte CQE while 500 bytes remain unread. The limit could have been reached. Debit only the bytes received by this invocation, sel->val - sr->done_io, and compare as unsigned so a limit above INT_MAX is accounted correctly. Non-bundle multishot requests keep sr->done_io at zero, so their accounting is unchanged. Fixes: 0ebc9a7ecf6a ("io_uring/net: Support multishot receive len cap") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Cheng Yongkang <teel4res@gmail.com> Link: https://patch.msgid.link/179328314078.648427.10086632105828535293@gmail.com [axboe: fix-up near-by incorrect comment while in there] Signed-off-by: Jens Axboe <axboe@kernel.dk>
3 daysio_uring/timeout: count cancelled timeouts in cq_timeoutsCheng Yongkang1-0/+3
io_timeout_cancel() posts the cancelled timeout's -ECANCELED CQE without advancing ctx->cq_timeouts. io_timeout_fn() and io_kill_timeout() advance it for every timeout CQE they post, and io_flush_timeouts() computes the number of non-timeout completions as seq = cached_cq_tail - cq_timeouts to compare against each off timeout's target_seq. The cancelled timeout's CQE is therefore counted as a regular completion, so every cancellation makes an already armed off timeout fire one completion early. A ring with a keep-alive timeout of off=4 completes it after two NOPs when one off=100 victim is cancelled through IORING_OP_ASYNC_CANCEL, and before any NOP when two victims are cancelled. The cancel CQE should count, but the cancelled timeouts' -ECANCELED CQEs must not: the expected counts are three and two NOPs respectively. Advance cq_timeouts when io_timeout_extract() succeeds, under timeout_lock and before the -ECANCELED completion is queued, matching io_timeout_fn() and io_kill_timeout(). The -ENOENT and -EALREADY paths post no new timeout CQE and keep their accounting. Both the ASYNC_CANCEL and the TIMEOUT_REMOVE path go through io_timeout_cancel(). Fixes: bfe68a221905 ("io_uring: off timeouts based only on completions") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Cheng Yongkang <teel4res@gmail.com> Link: https://patch.msgid.link/179328314078.648427.13761781546953594668@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
3 daysio_uring/napi: clean up list traversal with list_for_each_entry_safe()Anvik Loitongbam1-10/+4
Switch both loops to the standard list_for_each_entry_safe() pattern and remove the explanatory comment. Signed-off-by: Anvik Loitongbam <permissiontogallop@gmail.com> Reviewed-by: Steven Rostedt <rostedt@goodmis.org> Link: https://patch.msgid.link/20261029144745.23792-1-permissiontogallop@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring: defer foreign io-wq enqueues to task_workKyle Zeng1-2/+23
An IOPOLL ring without DEFER_TASKRUN can be reaped by a task other than the one that submitted the I/O. If a polled request is marked REQ_F_REISSUE, io_free_batch_list() calls io_queue_iowq() with the original tctx. Ordinary task exit can tear down tctx->io_wq after draining only the tracked requests. The live request pins the task, but not its io-wq, so the foreign task can race io_wq_put_and_exit() and enqueue through a freed or NULL queue. Forward foreign userspace enqueues to the owning task before accessing tctx->io_wq. Use a dedicated task_work callback so reissues still go straight to io-wq, and fail them if task_work is running in cancellation mode. Preserve the existing PF_KTHREAD cancellation path. This also covers the other callers of io_queue_iowq() without changing the worker-owned enqueue path. Signed-off-by: Kyle Zeng <kylebot@openai.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring/io-wq: save worker type before dropping its referenceKyle Zeng1-3/+5
io_wq_cancel_tw_create() inspects cb->func after calling io_worker_cancel_cb(). For an existing worker, that call can drop the last worker reference and wake io_worker_exit(). If the canceling task is preempted, the worker can be unlinked and freed by kfree_rcu() before the callback function is inspected. KASAN reports a slab-use-after-free read in this path. Save whether the callback belongs to an unpublished continuation worker while its reference is still held, then use the saved result for the conditional free. This preserves the existing accounting and frees only the worker allocated for the canceled continuation. Fixes: e6db6f9398da ("io_uring/io-wq: only free worker if it was allocated for creation") Cc: stable@vger.kernel.org Signed-off-by: Kyle Zeng <kylebot@openai.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring/cancel: drop sqd->lock while SQPOLL waitsChris Mason1-0/+20
An exiting SQPOLL thread calls io_uring_cancel_generic() with sqd->lock held, and keeps it across cond_resched() and the sleep until nothing is in flight anymore. A zero-copy send notification can't be canceled and stays pending as long as the peer doesn't read, so the lock is held for as long as a user cares to. io_ring_exit_work() needs it to park the thread, and so do IORING_REGISTER_IOWQ_AFF and IOWQ_MAX_WORKERS. With 64 such rings sharing the thread, every iou_exit slot sleeps on the lock and no ring gets freed for anyone. Drop the lock around cond_resched() and the sleep, like the main loop of the thread does. Each walk of ctx_list is still under one hold, and nothing is kept across the unlock. The thread drops its io-wq, frees its tctx and clears sqd->thread under one hold after the loop, so whoever holds the lock and finds sqd->thread set can still use them. Fixes: 63809137ebb5 ("io_uring: flush notifiers after sendzc") Signed-off-by: Chris Mason <mason@kernel.org> [axboe: adapted to the schedule_timeout() based loop] Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring/sqpoll: don't wait for the thread to exitChris Mason2-6/+25
io_sq_thread_stop() wakes the SQPOLL thread and waits for it to exit. The thread belongs to the thread group that created the ring, so a SIGSTOP or the cgroup freezer holds it in get_signal(), and the wake up doesn't change that. io_ring_exit_work() then sleeps in that wait until someone continues or kills the process. iou_exit has 64 slots, so 64 closed SQPOLL rings of a stopped process keep every other ring from being freed, for everyone. Don't wait. Set the stop bit, wake the thread, and let it exit when it gets to run again. The sqd can now outlive its last ring, so give it a second refcount with one reference for the rings and one for the thread, and free it with the last one. The thread can't reach a freed ring, rings leave ctx_list before dropping their reference, and the io-wq hash is refcounted. Fixes: 16efa4fce3b7 ("io_uring: allow IO worker threads to be frozen") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring: free the task context after a grace periodChris Mason2-1/+3
A task other than the owner can free a request, io_ring_exit_work() running the local task_work of a DEFER_TASKRUN ring for example, or io_do_iopoll() reaping completions. io_put_task() then takes the else branch: percpu_counter_sub(&tctx->inflight, 1); if (unlikely(atomic_read(&tctx->in_cancel))) wake_up(&tctx->wait); put_task_struct(tctx->task); The first line is what lets the owner leave io_uring_cancel_generic(), and on exec it frees the tctx right after. Nothing holds that off for the remaining three lines, the task reference only covers a tctx freed along with the task_struct. It used to work out because io_uring_del_tctx_node() took the uring_lock that the freeing side holds across io_put_task(), until that moved to tctx_lock. Free the tctx with kfree_rcu(), and enter an RCU read section in io_put_task() before the count is dropped. Fixes: 5623eb1ed035 ("io_uring/tctx: add separate lock for list of tctx's in ctx") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring/bpf-ops: clear bpf_ctx while submitting SQEsChris Mason1-1/+15
bpf_io_uring_submit_sqes() calls io_submit_sqes() from inside the loop program, with current->bpf_ctx set, and requests issued inline run with it set too. The socket code uses has_current_bpf_ctx() to recognize calls from bpf_setsockopt() and friends, where the caller holds the socket lock and has already been vetted, and skips both. So a SOCKET_URING_OP_SETSOCKOPT from the SQ passes sockopt_capable() without the capability, and runs without lock_sock(). A task with no capability can set SO_MARK, IP_TRANSPARENT or TCP_REPAIR, and two threads changing IP_OPTIONS on one socket, one through the ring, double free in no time. SOCK_DESTROY via IORING_OP_SENDMSG ends up in tcp_abort() without the lock the same way. Clear the run context around io_submit_sqes(). The SQEs come from userspace and must be issued like those of any other ring. They still run inside the program's RCU tasks trace read section, so a request that sleeps there holds up that grace period, but other request types do that already. Fixes: 890819248a86 ("io_uring/bpf-ops: add kfunc helpers") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring: free XArray nodes left by a failed storeChris Mason2-0/+4
A failed xa_store() can leave nodes without entries in the tree, and erasing every entry doesn't free those. An XArray needs xa_destroy() before it goes away, even an empty one. That was dropped for tctx->xa in commit ca6484cd308a ("io_uring: no need to call xa_destroy() on empty xarray") over a lockdep report from freeing the tctx in softirq context, and ctx->personalities never had it. Now that the nodes are charged, a store can fail at memory.max and the leaked nodes stay charged. Call xa_destroy() in io_uring_clean_tctx(), which the task runs itself in process context before the tctx is freed, in the error path of __io_uring_add_tctx_node(), and for ctx->personalities in io_ring_ctx_free(). Fixes: ca6484cd308a ("io_uring: no need to call xa_destroy() on empty xarray") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring: charge tctx nodes and personalitiesChris Mason2-3/+3
The io_tctx_node allocated the first time a task touches a ring, and the XArray nodes behind tctx->xa and ctx->personalities, are plain GFP_KERNEL. tctx->xa is indexed by the ring pointer, so nearly every entry needs nodes of its own, and a task gets one entry per ring it has used. 642 threads on 4000 rings held 2.3GB with 59MB charged against a 64MB memory.max. Allocate the node with GFP_KERNEL_ACCOUNT and set XA_FLAGS_ACCOUNT on both XArrays. Fixes: 0f2122045b94 ("io_uring: don't rely on weak ->files references") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring/rsrc: charge buffer arrays and nodes to memcgChris Mason1-3/+4
The io_mapped_ubuf of a registered buffer has one bio_vec per page, unless the pages coalesce into huge pages. Huge pages only count against RLIMIT_MEMLOCK once per ring, so a buffer that maps the same 2MB folio over and over in a way that defeats coalescing gets a full bvec array per registration while only the one folio counts as locked. 1GB of that registered in 100 slots took several times a 64MB memory.max, with 2.6MB charged. Allocate the io_mapped_ubuf and the io_rsrc_node with GFP_KERNEL_ACCOUNT. An object reused from the ring caches stays charged to whoever allocated it first, same as the io_kiocb cache. Fixes: de2939388be5 ("io_uring: improve registered buffer accounting for huge pages") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
4 daysio_uring/io-wq: no new workers once the exit has begunJosef Bacik1-0/+6
io_wq_exit_start() sets IO_WQ_BIT_EXIT, but worker creation task_work queued before that stays queued until io_wq_exit_workers() cancels it. In between the task runs its task_work while canceling requests, and a worker can still get created. That's a problem for exec. begin_new_exec() calls io_uring_task_cancel() after de_thread(), when it's supposedly the only thread left, and io_wq_exit_workers() only waits for ->worker_done, which a worker completes before do_exit(). So the exiting worker is still in the thread group, using the mm, files and sighand, while exec replaces them. Easy to hit with a signal pending when create_io_thread() fails and the retry gets queued right before execve(). Cancel the queued creation task_work as soon as the exit bit is set. Pending work that isn't otherwise canceled now ends with -ECANCELED when the io-wq is destroyed, rather than depending on whether the task happened to run its task_work first. Fixes: 685fe7feedb9 ("io-wq: eliminate the need for a manager thread") Signed-off-by: Josef Bacik <josef@toxicpanda.com> [axboe: the barrier is already upstream, see 0e5663856b69, only the cancel is new] Signed-off-by: Jens Axboe <axboe@kernel.dk>
5 daysio_uring: keep the drain active when a deferred drain request is startedJens Axboe1-7/+13
ecb6817b769f ends the drain when the dispatched drain request has posted its CQE and nothing else is deferred. But the deferred list is processed in between, and if the request it starts is itself a drain request, the drain is over before that one has even run. A request submitted after that point then runs ahead of it: 1. P0 in flight, D1 and D2 (both IOSQE_IO_DRAIN) deferred behind it 2. P0 completes, D1 is started 3. D1 completes, drain_done is set, D2 is started, the list is empty 4. IO_RING_F_DRAIN_ACTIVE is cleared with D2 still in flight Anything submitted now bypasses the drain. The same happens with D2 as the head of a link, as those aren't tracked in ->drain_req at all. Have io_queue_deferred() report whether it started a drain request, and don't end the drain if it did. Starting non-drain requests and ending it is still fine, they were only waiting on the drain request that just completed. Fixes: ecb6817b769f ("io_uring: end the drain when the drain request completes") Reported-by: Karl Mehltretter <kmehltretter@gmail.com> Link: https://lore.kernel.org/io-uring/20261027043323.98916-1-kmehltretter@gmail.com/ Cc: stable@vger.kernel.org Signed-off-by: Jens Axboe <axboe@kernel.dk>
5 daysMerge tag 'for-7.4/io_uring-dmabuf-20261023' of ↵Linus Torvalds6-55/+333
git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux Pull io_uring dma-buf support from Jens Axboe: "This adds native dma-buf support to the I/O path, exposed through io_uring. It's been in development for a while and should be ready to go now. - dma-buf file I/O infrastructure: a dma_buf_io_ctx created through a new ->init_dma_buf_io_ctx file operation, and a dma_buf_io_map holding the device DMA mapping. The two are split so a mapping can be invalidated and re-established underneath a live context, with the map counting in-flight requests so it can be torn down safely. - A new iov_iter type for dmabuf maps, and a dma map backed bio type for the block layer, with raw block device support on top. - nvme-pci backend implementing dma-buf backed requests, including SGL support. - io_uring dmabuf backed registered buffers, built on a reworked buffer registration structure with an extended update path, regbuf import flags, an uncloneable flag for buffer types that can't be cloned, and cloning support for registered dma-bufs" * tag 'for-7.4/io_uring-dmabuf-20261023' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: io_uring/dma-buf: don't fail fixed buffers without dma-buf support nvme-pci: detach dma-bufs only on removal block: reject dma-bufs larger than 4GiB io_uring/dma-buf: allow cloning registered dma-bufs dma-buf-io: document dma_buf_io_init_map dma-buf-io: fix typos in kernel docs block: fix indention for dma-buf checks io_uring/rsrc: add dmabuf backed registered buffers io_uring/rsrc: add regbuf import flags io_uring/rsrc: add uncloneable regbuf flag io_uring/rsrc: extend buffer update io_uring/rsrc: introduce buf registration structure nvme-pci: add SGL support for the dmabuf path nvme-pci: implement dma-buf backed requests nvme-pci: rename nvme_pci_sgl_set_data to nvme_pci_dma_iter_set_sgl block: add dma-buf support for raw bdev block: introduce dma map backed bio type block: always adjust bi_offset on bio_advance_iter iov_iter: add iterator type for dmabuf maps dma-buf: introduce initial file I/O infrastructure
5 daysio_uring/net: don't retry a non-blocking connect() that fails with -EAGAINDaan De Meyer1-0/+11
IORING_OP_CONNECT on an O_NONBLOCK AF_UNIX stream socket retries a connect that fails with -EAGAIN because the listener's backlog is full. Polling the client socket doesn't help: an unconnected stream socket reports EPOLLOUT and EPOLLHUP right away, before the backlog drains. So io_uring retries the connect until the apoll retry limit is hit, then punts the request to io-wq. With a full backlog, io_connect() runs 128 times in the submitting task and once more in a new io-wq worker. That worker stays in the task's thread group, so a later unshare(CLONE_NEWUSER) fails with -EINVAL. None of this changes the result. __sys_connect_file() adds the socket's own O_NONBLOCK to every attempt, so the attempt from io-wq fails with -EAGAIN as well. That -EAGAIN becomes the CQE result, and connect(2) returns the same -EAGAIN. Let's complete the request with -EAGAIN right away when the socket has O_NONBLOCK set, like connect(2) does. io_accept() already completes -EAGAIN this way for IORING_ACCEPT_DONTWAIT. -EINPROGRESS still waits for the connection to complete. A blocking socket still ends up in io-wq, where the connect sleeps until the listener accepts. Fixes: f8e85cf255ad ("io_uring: add support for IORING_OP_CONNECT") Signed-off-by: Daan De Meyer <daan@amutable.com> Link: https://patch.msgid.link/20261027-b4-io-uring-connect-eagain-v1-1-f4e3aaaa49ee@amutable.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
6 daysio_uring/register: enforce per-task restrictions in io_uring_register_blind()Dominik Maier1-0/+7
When io_uring_register(2) is invoked with fd == -1, it dispatches directly to io_uring_register_blind() without checking current->io_uring_restrict. As a result, a task with per-task register restrictions installed via IORING_REGISTER_RESTRICTIONS can still invoke blind registration opcodes such as IORING_REGISTER_SEND_MSG_RING even when those opcodes are not in the task's allowed register_op bitmap. Check current->io_uring_restrict->register_op in io_uring_register_blind() before dispatching blind registration opcodes. Fixes: ed82f35b926b ("io_uring: allow registration of per-task restrictions") Assisted-by: ARTIST LLM Signed-off-by: Dominik Maier <dmnk@google.com> Link: https://patch.msgid.link/20261022232121.2538616-1-dmnk@google.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
6 daysio_uring/net: mask socket type with SOCK_TYPE_MASK in io_socket_bpf_populate()Dominik Maier1-1/+1
When an IORING_OP_SOCKET request is prepared in io_socket_prep(), sock->type retains creation flags such as SOCK_CLOEXEC and SOCK_NONBLOCK until __sys_socket_file() masks them off with SOCK_TYPE_MASK during execution. However, io_socket_bpf_populate() copies sock->type into bctx->socket.type without masking off ~SOCK_TYPE_MASK. As a result, a cBPF filter inspecting bctx->socket.type against socket types such as SOCK_DGRAM or SOCK_STREAM can be bypassed by ORing SOCK_CLOEXEC or SOCK_NONBLOCK into the socket type. Mask sock->type with SOCK_TYPE_MASK when populating bctx->socket.type. Fixes: cff1c26b4223 ("io_uring/net: allow filtering on IORING_OP_SOCKET data") Assisted-by: ARTIST LLM Signed-off-by: Dominik Maier <dmnk@google.com> Link: https://patch.msgid.link/20261022232120.2537530-1-dmnk@google.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
6 daysio_uring/net: Remove useless min_not_zero() usageClément Léger1-1/+1
In the else arm, sel->val is necessarily 0 so the min_not_zero() actually always returns kmsg->msg.msg_inq. Remove the min_not_zero() usage and replace it with kmsg->msg.msg_inq. Signed-off-by: Clément Léger <cleger@meta.com> Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de> Link: https://patch.msgid.link/20261023144953.3584118-1-cleger@meta.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
6 daysio_uring/net: keep recvmsg buffer select length within MAX_RW_COUNTYichong Chen1-0/+1
io_recvmsg() takes the transfer length from the ring provided buffer when sqe->len is 0, and such a buffer can be up to 4G. min_ret is an int, so 2G or more makes it negative and the (ret < min_ret) block is skipped, and the oversized length reaches the socket layer unchanged: an empty socket then completes with 0 instead of arming poll, and a short read is reported as complete. Clamp the length to MAX_RW_COUNT, as io_recv() does. Fixes: c7fb19428d67 ("io_uring: add support for ring mapped supplied buffers") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Link: https://patch.msgid.link/20261023112209.87979-1-chenyichong@uniontech.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
6 daysio_uring/kbuf: advance head when a pickup empties the buffer ringYichong Chen1-1/+3
io_ring_buffers_peek() flags the request with REQ_F_BL_EMPTY if the buffers it picked were the last ones available, comparing head to tail. When the loop breaks because max_len was exhausted the buffer was picked, but head is left pointing at it, so the flag isn't set if it was the last buffer. A bundle receive then retries, finds no buffer, and the request, which has received data, is marked as failed on account of the -ENOBUFS. That severs a link, and ends a multishot. Fixes: 35c8711c8fc4 ("io_uring/kbuf: add helpers for getting/peeking multiple buffers") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Link: https://patch.msgid.link/20261023091711.83481-1-chenyichong@uniontech.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
8 daysMerge tag 'for-7.4/io_uring-20261021' of ↵Linus Torvalds30-280/+1071
git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux Pull io_uring updates from Jens Axboe: "The bulk of this is a big robustness pass over cancelation, io-wq, timeouts, and poll. Outside of that: - Large series from Josef hardening the cancelation, io-wq, timeout, poll, and wait paths. Fixes for lost wakeups and lost cancels as io-wq arms poll/timeouts, work stranding on worker exit, CQE32 resize handling, napi entry timeouts, and a pile of smaller correctness issues across the board - Rework of how io-wq posts completions, posting from the last request reference and dropping the request file before the completion, and running ring release cancelations synchronously - canceling and waiting for all in-flight requests and dropping registered files and buffers at release time - Don't charge the SQ/CQ rings or provided buffer rings to RLIMIT_MEMLOCK, which the region API conversion had started doing - Split io_uring_cmd_set_res() out from io_uring_cmd_done() so a command can set the result from its ->end_io() handler, used by nvme - CQE32 ring fixes for the free entry check, aux CQE big_cqe zeroing, and the dummy skip CQE - Timeout fixes for sequence handling and multishot updates - net fixes for MSG_TRUNC buffer overconsumption and keeping recv buffer select length within MAX_RW_COUNT - Wake real-time waiters from hard interrupt context - Don't spin on local work an exiting task can't run, reachable by an unprivileged user - Various other fixes and cleanups" * tag 'for-7.4/io_uring-20261021' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: (75 commits) io_uring: end the drain when the drain request completes io_uring/futex: return a wait's data to the cache when it fails to arm io_uring/wait: wake real-time waiters from hard interrupt context io_uring/waitid: return -EAGAIN for a non-blocking pidfd io_uring/net: keep recv buffer select length within MAX_RW_COUNT io_uring/waitid: prevent cancel reference wrap io_uring/poll: don't loop on HUP with multiple references io_uring/timeout: don't lose a cancel as io-wq arms a timeout io_uring/timeout: don't flush with the sequence behind the last flush io_uring/timeout: don't put a sequence target behind the last flush io_uring/poll: avoid retry wakeup loss when dropping ownership io_uring: look up the file before queueing to io-wq io_uring/timeout: don't end a linked timeout with 1 io_uring/timeout: no ABS update of multishot timeouts io_uring/net: don't retry recv on uncommitted buffers io_uring: don't pass restart error codes to userspace io_uring/openclose: keep the lock in io_pipe_fixed() io_uring/sqpoll: let the thread sleep on disabled rings io_uring/kbuf: handle index wrap in last buffer check io_uring/zcrx: fix buffer offsets in areas above 4GB ...
10 daysio_uring/dma-buf: don't fail fixed buffers without dma-buf supportAnuj Gupta1-2/+2
io_attach_dmabuf_map() is called for every fixed read/write, but returns -EOPNOTSUPP when CONFIG_DMA_SHARED_BUFFER is disabled before checking whether the request uses a dma-buf at all. So READ_FIXED and WRITE_FIXED fail for ordinary registered buffers. Check REQ_F_DMABUF first. Fixes: 62e4bf5b25d4 ("io_uring/rsrc: add dmabuf backed registered buffers") Signed-off-by: Anuj Gupta <anuj20.g@samsung.com> Link: https://patch.msgid.link/20261022132027.2293931-1-anuj1072538@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
11 daysMerge tag 'timers-core-2026-10-20' of ↵Linus Torvalds1-1/+1
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull timer core updates from Thomas Gleixner: "Updates for the core timekeeping and timers subsystem: - Futher cleanups for the POSIX timer exit/exec related code to simplify the code flow and to make it more robust against future changes. - Prevent tearing of timekeeper::ktime_sec which can be accessed without the sequence count protection. The timekeeper is updated by memcpy() with an uneven sequence count to force readers into the retry path. On 64-bit machine the ktime_sec member can be accessed atomically without the sequence count protection. That is only correct when the update side memcpy() guarantees atomicity at the 64-bit granularity. That's not guaranteed due to debug options, compilers and instruction availability. If the memcpy() does not provide the atomicity then the unprotected readers can observe store tearing. To prevent this write the ktime_sec member before the memcpy() so that a non-atomic memcpy() will write the same data. A similar fix has been done for the xtime_sec member, but the ktime_sec equivalent was missed. - Prevent time64_to_tm() day truncation on 32-bit kernels The function receives a 64-bit seconds value but stores the quotient of the computation in a long, which truncates the result for large input values. Cure this by using div_s64_rem() which stores the quotient in s64 and only leaves the seconds-within-day reminder in a long, which is guaranteed to fit. This fix comes with a corresponding kunit test to prevent further mishaps. - Mark data-racy accesses to the hrtimer_sleeper::task member. The recent updates to KCSAN flagged these benign races. Annotate them with new helper functions, convert all existing usage sites and mark the task member private after that so that future users which fail to use the helpers can be detected automatically. - Address similar benign KCSAN flagged issues in the hrtimer, timer and timer migration code. - Fixes for a few selftest issues" * tag 'timers-core-2026-10-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (26 commits) selftests/timers: clocksource-switch: Fix unchecked open()/read() selftests: timers: Measure the CPU timers on the clock they count selftests: timers: Count what tick is worth in the drift estimate time/kunit: Add time64_to_tm() case beyond 32-bit day count time: Prevent time64_to_tm() day truncation on 32-bit timekeeping: Use READ_ONCE/WRITE_ONCE() for ktime_sec to prevent tearing timers/migration: Mark racy updates to tmigr_event::ignore field timers: Mark racy updates to hlist_node::pprev field hrtimer: Apply READ_ONCE() to lockless base->running loads hrtimer: Mark the hrtimer_sleeper structure's ->task field __private hrtimer: Update hrtimer_resolution only if value changes futex: Use accessor for hrtimer_sleeper ->task field in requeue rtmutex: Use accessor for hrtimer_sleeper ->task field net: pktgen: Use accessor for hrtimer_sleeper ->task field timers: Use accessor for hrtimer_sleeper ->task field in sleep_timeout.c futex: Use accessor for hrtimer_sleeper ->task field in waitwake.c io-uring/rw: Use accessor for hrtimer_sleeper ->task field wait: Use accessor for hrtimer_sleeper ->task field aio: Use accessor for hrtimer_sleeper ->task field hrtimer: Mark data-racy accesses to hrtimer_sleeper ->task field ...
12 daysio_uring: end the drain when the drain request completesJens Axboe1-3/+39
Since requests are drained based on allocated requests, the drain stays active after the drain request has posted its CQE, until it is freed and a new request finds the defer list empty. A drain request run by io-wq is freed only after the worker drops its reference, so a request submitted after the drain completed can still be deferred behind it, and get issued much later than the application expects. A drain request dispatched from the defer list runs alone. Track it, and end the drain when its CQE is flushed and nothing else is deferred. Have io-wq complete drain requests through task_work, so that this happens under ->uring_lock before the CQE is visible. Linked drain requests keep waiting until the link is freed. Reported-by: Wei Gao <wegao@suse.com> Link: https://lore.kernel.org/io-uring/20261018070154.16944-1-wegao@suse.com/ Fixes: 8fb7aee05591 ("io_uring: drain based on allocates reqs") Cc: stable@vger.kernel.org Tested-by: Wei Gao <wegao@suse.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
12 daysio_uring/futex: return a wait's data to the cache when it fails to armAustin Schuh1-1/+5
io_futex_wait() takes its io_futex_data from ctx->futex_cache, and a completed wait gives it back in io_futex_complete(). A wait that fails to arm kfree()s it instead. The usual failure is -EAGAIN from futex_wait_setup(): the futex word no longer holds the expected value. That is routine for a waiter that re-arms with the value it last read, since the word changes whenever there is something to wake for. Each such failure takes an object out of the cache for good, so the cache drains and from then on waits allocate. The cache exists so that arming a wait doesn't have to go to the slab allocator, and that matters most to the waiters that re-arm the most: event loops, often real-time ones. A kmalloc() or kfree() that misses the per-CPU slab takes the node's list_lock, shared with every other user of that kmalloc size on the system, and may go on to the page allocator. On PREEMPT_RT list_lock is a sleeping lock. A real-time task that finds it held waits for the holder, which may be any task on any CPU, to get to run and release it. Priority inheritance boosts the holder only up to the waiter's priority, so the waiter still sits behind whatever outranks that on the holder's CPU, such as threaded interrupt handlers. Re-arming a futex wait should not depend on any of that. Put the data back in the cache on that path too, while the submit lock still protects it. In an event loop re-arming one IORING_OP_FUTEX_WAIT per message under load, 0.39 arms per message failed with -EAGAIN, and io_futex_wait() did 0.39 kmalloc()s and kfree()s per message. With this change, 100,000 waits that all fail with -EAGAIN do one kmalloc() in total. Fixes: 194bb58c6090 ("io_uring: add support for futex wake and wait") Assisted-by: LLM Signed-off-by: Austin Schuh <austin.linux@gmail.com> Link: https://patch.msgid.link/20261019231243.802569-1-austin.linux@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
13 daysMerge tag 'vfs-7.4-rc1.file' of ↵Linus Torvalds1-4/+4
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull file table updates from Christian Brauner: "This annotates struct fdtable's fd array with __counted_by_ptr so KASAN and the fortified functions can bounds check it against max_fds and adds a KUnit suite for fdtable. A follow-up uses __struct_size() in the test since sparse doesn't know __builtin_dynamic_object_size(). FD_PREPARE() is simplified. It was built as an ACQUIRE-style guard on infrastructure that was never needed. The ACQUIRE machinery and CLASS_INIT() go away, the variable is declared with __cleanup() directly, struct fd_prepare loses its err field since the fd either holds the descriptor or the error, and callers get a const pointer to the guard behind a UNIQUE_ID() name so they can't shadow it. Code generation is identical" * tag 'vfs-7.4-rc1.file' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: file: make struct fd_prepare const and kill its err field cleanup: remove CLASS_INIT() file: declare the FD_PREPARE() variable with __cleanup() directly file: simplify FD_PREPARE() vfs: use __struct_size() in the fdtable KUnit test vfs: Add KUnit tests for fdtable vfs: Annotate struct fdtable's fd field with __counted_by_ptr
13 daysMerge tag 'kernel-7.4-rc1.signal' of ↵Linus Torvalds1-0/+2
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull signal handling updates from Christian Brauner: "This stops TIF_NOTIFY_SIGNAL from interrupting work that can't be restarted and fixes a bunch of coredump and signal bugs. TIF_NOTIFY_SIGNAL kicks a task out of an uninterruptible sleep so it returns to userspace, runs its task work and goes back to sleep. That breaks coredumps: dump_interrupted() only lets fatal signals interrupt a dump and writes to a regular file ignore TIF_NOTIFY_SIGNAL. But the pipe and the socket paths check signal_pending() Adeep down in code that is shared with regular syscalls and bail. So a crashing process with io_uring requests in flight loses most of its coredump. In the selftest an unfixed kernel delivers 357324 of at least 5111808 bytes. And io_uring isn't the only source. klp_send_signals(), bpf_task_work_schedule_signal(), landlock's tsync, kthread_stop() and the printk kunit test raise the bit as well, some of them from irq context against any task. So this can't be fixed per subsystem and the state has to be per-task and ambient. Add PF_NO_NOTIFY_SIGNAL and no_notify_signal_save()/restore() helpers modelled on memalloc_nofs_save(). Inside such a section signal_pending() ignores TIF_NOTIFY_SIGNAL. Coredumps, the smb send path, which hand-rolled its own version of this, and the pid namespace reaper, which busy-looped when the bit kept getting raised, are converted. The second part is a set of fixes that fell out of looking at the coredump code with kres and modelling it in TLA+: - coredump_finish() woke the parked threads without holding rcu. A parked thread can exit on a spurious wakeup and be freed before wake_up_process() takes its pi_lock. - Only SIGKILL and the freezers interrupt a dump now and the three freezers agree. Power management and cgroup v1 freezing aborted a dump while a cgroup v2 freeze either waited for the dump or cut it short depending on where the core went. - io-wq set its exit bit without a barrier against the task work that creates workers. On weakly ordered architectures exit could hang on worker_done. - retarget_shared_pending() slingshotted a shared signal to the dumper when a zapped sibling restored its signal mask. That set TIF_SIGPENDING on the dumper and truncated the core. - A tracer could clear the signal mask of a user worker with PTRACE_SETSIGMASK and inject a coredump signal. An io-wq worker of an SQPOLL ring dumping core deadlocks the whole group. PTRACE_SETSIGMASK is refused for user workers now and __set_task_blocked() enforces the fork-time mask. - exec cancels io_uring requests before de_thread() so a worker creation queued as task work can't add a thread to a thread group that de_thread() just took down. - No io threads are created from a PF_SIGNALED or PF_POSTCOREDUMP creator anymore. Such a worker was invisible to zap_process() but still decremented threads_remaining on exit so the dumper could leave coredump_wait_inactive() early. Also included are a comment that do_each_pid_task() needs tasklist_lock, a READ_ONCE() in pid_alive() and a regression test for fork() into a pid namespace whose ancestor lost its init" * tag 'kernel-7.4-rc1.signal' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (21 commits) pid: use READ_ONCE() in pid_alive() selftests: pid_namespace: test fork with dead ancestor pid: document that do_each_pid_task() needs tasklist_lock signal: enforce the user worker signal mask in __set_task_blocked() fork: use SIG_KERNEL_ONLY_MASK for the user worker signal mask fork: don't create io threads once PF_POSTCOREDUMP is set fork: move the coredump and exec checks into create_io_thread() exec: cancel io_uring requests before de_thread() selftests/coredump: expect PTRACE_SETSIGMASK to be refused on a user worker selftests/coredump: test a user worker as the coredumping thread ptrace: refuse to change the signal mask of a user worker selftests/coredump: test shared signal retargeting during a dump signal: only SIGKILL and the freezers interrupt a coredumping task signal: don't retarget shared signals in a dying thread group io-wq: order the exit bit against worker creation task work coredump: hold RCU while releasing parked threads pid_namespace: prevent TIF_NOTIFY_SIGNAL from interrupting the reaper smb: prevent TIF_NOTIFY_SIGNAL from interrupting selftests/coredump: test that TIF_NOTIFY_SIGNAL doesn't truncate a coredump coredump: prevent TIF_NOTIFY_SIGNAL from interrupting coredumps ...
13 daysio_uring/wait: wake real-time waiters from hard interrupt contextAustin Schuh1-3/+13
Since commit cebf123c634a ("io_uring: implement our own schedule timeout handling"), a CQ wait with a timeout sleeps on io_uring's own hrtimer instead of an hrtimer sleeper. On PREEMPT_RT, an hrtimer that isn't marked for hard interrupt expiry expires in the per-CPU ktimers thread, which runs at SCHED_FIFO 1. A real-time task waiting in io_uring_enter() is therefore not woken at its deadline while any other real-time task is runnable on its CPU: the wakeup waits until every one of them has blocked. hrtimer sleepers, which schedule_hrtimeout_range_clock() used to give io_uring, don't have this problem: __hrtimer_setup_sleeper() marks the timer hard when the sleeping task is in a real-time or deadline class. Both of io_uring's callbacks are fine in hard interrupt context: io_cqring_timer_wakeup() sets a flag and calls wake_up_process(), and io_cqring_min_timer_wakeup() only reads ring state, under RCU, before doing the same or re-arming the timer. Apply the sleeper rule to them. Measured on a Jetson Orin Nano running 6.18.39-rt with this change backported: a SCHED_FIFO 40 task waits in io_uring_enter() for 40,000 deadlines 500us apart, while a SCHED_FIFO 20 task runs bursts of up to 1ms on the same CPU. Before, 6,647 wakeups were more than 100us late, the latest by 1,040us, and 2,758 deadlines passed without a wakeup at all. After, none were more than 100us late and the latest was 18us. This mirrors epoll: epoll_pwait2() waits on an hrtimer sleeper, so its timeout is already hard for real-time tasks, and on the same setup it was never more than 17us late. Fixes: cebf123c634a ("io_uring: implement our own schedule timeout handling") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Austin Schuh <austin.linux@gmail.com> Link: https://patch.msgid.link/20261017171726.601443-1-austin.linux@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
13 daysio_uring/waitid: return -EAGAIN for a non-blocking pidfdNickolai Zeldovich1-0/+4
IORING_OP_WAITID on a pidfd opened with PIDFD_NONBLOCK completes at once with res 0 and an all-zero siginfo when the child has not changed state, although WNOHANG was not requested. waitid(2) with the same arguments fails with -EAGAIN. An application that submits the same request it would pass to waitid(2) and treats res 0 as "the child changed state" sees si_signo 0 and si_pid 0 instead. kernel_waitid_prepare() turns an O_NONBLOCK pidfd into WNOHANG in wo->wo_flags. kernel_waitid() then maps the resulting 0 return to -EAGAIN when the caller did not ask for WNOHANG itself, as added in commit ba7d25f3dff6 ("exit: support non-blocking pidfds"). io_waitid() uses kernel_waitid_prepare() and __do_wait() directly and does not do that mapping. Do the same check in io_waitid() before completing the request. Only the inline path needs it: with WNOHANG set, __do_wait() never returns -ERESTARTSYS, so such a request is never armed on the wait queue. Reproduced on x86_64 under QEMU: with a PIDFD_NONBLOCK pidfd of a running child and options = WEXITED, waitid(2) fails with -EAGAIN and IORING_OP_WAITID completed with res 0 before the change; it completes with res -EAGAIN after it. Fixes: f31ecf671ddc ("io_uring: add IORING_OP_WAITID support") Assisted-by: LLM Signed-off-by: Nickolai Zeldovich <nickolai@csail.mit.edu> Link: https://patch.msgid.link/20261018025824.799245-1-nickolai@csail.mit.edu Signed-off-by: Jens Axboe <axboe@kernel.dk>
13 daysio_uring/net: keep recv buffer select length within MAX_RW_COUNTTamaki Yanagawa1-0/+2
Since commit dcbd1c054848 ("io_uring/net: let io_recv_buf_select return the length of the buffer region"), io_recv_buf_select() returns the selected length as an int. For a non-bundle recv with sqe->len == 0 the length comes from the ring provided buffer, which can be up to 4G, so a buffer of 2G or more makes io_recv() f