[rlc-10/6.12.0-211.43.1.el10_2] Multiple patches tested (41 commits) - #1539
Open
ciq-kernel-automation[bot] wants to merge 41 commits into
Open
Conversation
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 92270d0 This function is needed by fuse_uring.c to clean ring queues, so make it non static. Especially in non-static mode the function name 'end_requests' should be prefixed with fuse_ Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 92270d0) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 867d93d Another preparation patch, as this function will be needed by fuse/dev.c and fuse/dev_uring.c. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 867d93d) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 88be7aa These are needed by fuse-over-io-uring. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 88be7aa) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 7ccd86b upstream-diff | Context conflict on missing fs/fuse/fuse_i.h commit 4174867 -virtiofs: use pages instead of pointer for kernel direct IO This change sets up FUSE operations to always have headers in args.in_args[0], even for opcodes without an actual header. This step prepares for a clean separation of payload from headers, initially it is used by fuse-over-io-uring. For opcodes without a header, we use a zero-sized struct as a placeholder. This approach: - Keeps things consistent across all FUSE operations - Will help with payload alignment later - Avoids future issues when header sizes change Op codes that already have an op code specific header do not need modification. Op codes that have neither payload nor op code headers are not modified either (FUSE_READLINK and FUSE_DESTROY). FUSE_BATCH_FORGET already has the header in the right place, but is not using fuse_copy_args - as -over-uring is currently not handling forgets it does not matter for now, but header separation will later need special attention for that op code. Correct the struct fuse_args->in_args array max size. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 7ccd86b) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 24fe962 upstream-diff | Context diff due to missing commit on fs/fuse/Makefile 2b3933b - fuse: enable dynamic configuration of fuse max pages limit (FUSE_MAX_MAX_PAGES) Context difference due to future feature enabled earlier in git log order as well. This adds basic support for ring SQEs (with opcode=IORING_OP_URING_CMD). For now only FUSE_IO_URING_CMD_REGISTER is handled to register queue entries. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 24fe962) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit d0f9c62 Move 'struct fuse_copy_state' and fuse_copy_* functions to fuse_dev_i.h to make it available for fuse-io-uring. 'copy_out_args()' is renamed to 'fuse_copy_out_args'. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit d0f9c62) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit f773a7c Add special fuse-io-uring into the fuse argument copy handler. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit f773a7c) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 3821336 fuse-over-io-uring uses existing functions to find requests based on their unique id - make these functions non-static. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 3821336) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit c090c8a This adds support for fuse request completion through ring SQEs (FUSE_URING_CMD_COMMIT_AND_FETCH handling). After committing the ring entry it becomes available for new fuse requests. Handling of requests through the ring (SQE/CQE handling) is complete now. Fuse request data are copied through the mmaped ring buffer, there is no support for any zero copy yet. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit c090c8a) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 4a9bfb9 On teardown struct file_operations::uring_cmd requests need to be completed by calling io_uring_cmd_done(). Not completing all ring entries would result in busy io-uring tasks giving warning messages in intervals and unreleased struct file. Additionally the fuse connection and with that the ring can only get released when all io-uring commands are completed. Completion is done with ring entries that are a) in waiting state for new fuse requests - io_uring_cmd_done is needed b) already in userspace - io_uring_cmd_done through teardown is not needed, the request can just get released. If fuse server is still active and commits such a ring entry, fuse_uring_cmd() already checks if the connection is active and then complete the io-uring itself with -ENOTCONN. I.e. special handling is not needed. This scheme is basically represented by the ring entry state FRRS_WAIT and FRRS_USERSPACE. Entries in state: - FRRS_INIT: No action needed, do not contribute to ring->queue_refs yet - All other states: Are currently processed by other tasks, async teardown is needed and it has to wait for the two states above. It could be also solved without an async teardown task, but would require additional if conditions in hot code paths. Also in my personal opinion the code looks cleaner with async teardown. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 4a9bfb9) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit ba74ba5 These functions are also needed by fuse-over-io-uring. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit ba74ba5) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit c2c9af9 This prepares queueing and sending foreground requests through io-uring. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit c2c9af9) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 857b026 This prepares queueing and sending background requests through io-uring. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 857b026) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit b6236c8 When the fuse-server terminates while the fuse-client or kernel still has queued URING_CMDs, these commands retain references to the struct file used by the fuse connection. This prevents fuse_dev_release() from being invoked, resulting in a hung mount point. This patch addresses the issue by making queued URING_CMDs cancelable, allowing fuse_dev_release() to proceed as expected and preventing the mount point from hanging. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit b6236c8) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bernd@bsbernd.com> commit 3393ff9 upstream-diff | Context conflict on missing fs/fuse/fuse_i.h commit 4174867 -virtiofs: use pages instead of pointer for kernel direct IO Avoid races and block request allocation until io-uring queues are ready. This is a especially important for background requests, as bg request completion might cause lock order inversion of the typical queue->lock and then fc->bg_lock fuse_request_end spin_lock(&fc->bg_lock); flush_bg_queue fuse_send_one fuse_uring_queue_fuse_req spin_lock(&queue->lock); Signed-off-by: Bernd Schubert <bernd@bsbernd.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 3393ff9) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 786412a All required parts are handled now, fuse-io-uring can be enabled. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 786412a) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 2d4fde5 The enable_uring module parameter allows administrators to enable/disable io-uring support for FUSE at runtime. However, disabling io-uring while connections already have it enabled can lead to an inconsistent state. Fix this by keeping io-uring enabled on connections that were already using it, even if the module parameter is later disabled. This ensures active FUSE mounts continue to function correctly. Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Luis Henriques <luis@igalia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 2d4fde5) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Joanne Koong <joannelkoong@gmail.com> commit d9ecc77 There is a race condition leading to a kernel crash from a null dereference when attemping to access fc->lock in fuse_uring_create_queue(). fc may be NULL in the case where another thread is creating the uring in fuse_uring_create() and has set fc->ring but has not yet set ring->fc when fuse_uring_create_queue() reads ring->fc. There is another race condition as well where in fuse_uring_register(), ring->nr_queues may still be 0 and not yet set to the new value when we compare qid against it. This fix sets fc->ring only after ring->fc and ring->nr_queues have been set, which guarantees now that ring->fc is a proper pointer when any queues are created and ring->nr_queues reflects the right number of queues if ring is not NULL. We must use smp_store_release() and smp_load_acquire() semantics to ensure the ordering will remain correct where fc->ring is assigned only after ring->fc and ring->nr_queues have been assigned. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Link: https://lore.kernel.org/r/20250318003028.3330599-1-joannelkoong@gmail.com Fixes: 24fe962 ("fuse: {io-uring} Handle SQEs - register commands") Acked-by: Miklos Szeredi <mszeredi@redhat.com> Reviewed-by: Bernd Schubert <bschubert@ddn.com> Signed-off-by: Christian Brauner <brauner@kernel.org> (cherry picked from commit d9ecc77) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Luis Henriques <luis@igalia.com> commit d550114 When mounting a user-space filesystem using io_uring, the initialization of the rings is done separately in the server side. If for some reason (e.g. a server bug) this step is not performed it will be impossible to unmount the filesystem if there are already requests waiting. This issue is easily reproduced with the libfuse passthrough_ll example, if the queue depth is set to '0' and a request is queued before trying to unmount the filesystem. When trying to force the unmount, fuse_abort_conn() will try to wake up all tasks waiting in fc->blocked_waitq, but because the rings were never initialized, fuse_uring_ready() will never return 'true'. Fixes: 3393ff9 ("fuse: block request allocation until io-uring init is complete") Signed-off-by: Luis Henriques <luis@igalia.com> Link: https://lore.kernel.org/r/20250306111218.13734-1-luis@igalia.com Acked-by: Miklos Szeredi <mszeredi@redhat.com> Reviewed-by: Bernd Schubert <bschubert@ddn.com> Signed-off-by: Christian Brauner <brauner@kernel.org> (cherry picked from commit d550114) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Luis Henriques <luis@igalia.com> commit 841c7b8 Function fuse_uring_create() is used only from dev_uring.c and does not need to be exposed in the header file. Furthermore, it has the wrong signature. While there, also remove the 'struct fuse_ring' forward declaration. Signed-off-by: Luis Henriques <luis@igalia.com> Reviewed-by: Bernd Schubert <bschubert@ddn.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 841c7b8) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Bernd Schubert <bschubert@ddn.com> commit 09098e6 task-A (application) might be in request_wait_answer and try to remove the request when it has FR_PENDING set. task-B (a fuse-server io-uring task) might handle this request with FUSE_IO_URING_CMD_COMMIT_AND_FETCH, when fetching the next request and accessed the req from the pending list in fuse_uring_ent_assign_req(). That code path was not protected by fiq->lock and so might race with task-A. For scaling reasons we better don't use fiq->lock, but add a handler to remove canceled requests from the queue. This also removes usage of fiq->lock from fuse_uring_add_req_to_ring_ent() altogether, as it was there just to protect against this race and incomplete. Also added is a comment why FR_PENDING is not cleared. Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support") Cc: <stable@vger.kernel.org> # v6.14 Reported-by: Joanne Koong <joannelkoong@gmail.com> Closes: https://lore.kernel.org/all/CAJnrk1ZgHNb78dz-yfNTpxmW7wtT88A=m-zF0ZoLXKLUHRjNTw@mail.gmail.com/ Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 09098e6) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Joanne Koong <joannelkoong@gmail.com> commit 2d06680 When the ring is allocated, it is kzalloc-ed. ring->queue_refs will already be initialized to 0 by default. It does not need to be atomically set to 0. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Bernd Schubert <bschubert@ddn.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 2d06680) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478 cve CVE-2025-68791 RFE: FUSE_IO_URING commit-author Cheng Ding <cding@ddn.com> commit 6e0d7f7 upstream-diff | Context diffs from missing upstream type changes (bool write, is_uring = true) and surrounding declarations Fix a possible reference count leak of payload pages during fuse argument copies. [Joanne: simplified error cleanup] Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support") Cc: stable@vger.kernel.org # v6.14 Signed-off-by: Cheng Ding <cding@ddn.com> Signed-off-by: Bernd Schubert <bschubert@ddn.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 6e0d7f7) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 cve CVE-2025-68805 RFE: FUSE_IO_URING commit-author Joanne Koong <joannelkoong@gmail.com> commit 95c39ee When a request is terminated before it has been committed, the request is not removed from the queue's list. This leaves a dangling list entry that leads to list corruption and use-after-free issues. Remove the request from the queue's list for terminated non-committed requests. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support") Cc: stable@vger.kernel.org Reviewed-by: Bernd Schubert <bschubert@ddn.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 95c39ee) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 cve CVE-2026-64264 RFE: FUSE_IO_URING commit-author Chris Mason <clm@meta.com> commit 3a0a8bc copy_from_user() returns the number of bytes not copied as an unsigned residual on failure (1..sizeof(struct fuse_out_header)). fuse_uring_commit stores that residual in ssize_t err, sets req->out.h.error to -EFAULT, then jumps to out: with err still holding the positive residual. err = copy_from_user(&req->out.h, &ent->headers->in_out, sizeof(req->out.h)); if (err) { req->out.h.error = -EFAULT; goto out; /* err is the positive residual */ } ... out: fuse_uring_req_end(ent, req, err); fuse_uring_req_end() then runs if (error) req->out.h.error = error; which overwrites the just-assigned -EFAULT with the positive residual. FUSE callers such as fuse_simple_request() test err < 0 to detect failure, so the positive value is interpreted as success and the caller proceeds with an uninitialised or partial req->out.args. Fix by assigning err = -EFAULT in the failure branch before jumping to out, so fuse_uring_req_end() receives a negative errno and sets req->out.h.error to -EFAULT. Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support") Cc: stable@vger.kernel.org Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Assisted-by: kres (claude-opus-4-7) Signed-off-by: Chris Mason <clm@meta.com> Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 3a0a8bc) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 cve CVE-2026-64588 RFE: FUSE_IO_URING commit-author Chris Mason <clm@meta.com> commit 46725a0 On weakly-ordered architectures, the store to fiq->ops can be reordered past the store to ring->ready, allowing a CPU that sees ring->ready == true via fuse_uring_ready() to dispatch requests through a stale fiq->ops pointer. Upgrade the store to smp_store_release() and the load in fuse_uring_ready() to smp_load_acquire() so that the preceding WRITE_ONCE(fiq->ops, ...) is visible to any CPU that observes ring->ready == true. Additionally, fuse_uring_do_register() publishes ring->ready with WRITE_ONCE() but the fast-path check reads it with a plain load. This is a marked-vs-unmarked access that KCSAN will flag. Wrap it in READ_ONCE() to mark it without adding unnecessary ordering. Also wrap the fc->ring load in fuse_uring_ready() in READ_ONCE() to prevent the compiler from reloading it between the NULL check and the dereference. Fixes: c2c9af9 ("fuse: Allow to queue fg requests through io-uring") Cc: stable@vger.kernel.org Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Assisted-by: kres (claude-opus-4-7) Signed-off-by: Chris Mason <clm@meta.com> Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 46725a0) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 cve CVE-2026-68095 RFE: FUSE_IO_URING commit-author Joanne Koong <joannelkoong@gmail.com> commit 952b5d3 upstream-diff | fch->lock/fch->connected changed to fc->lock/fc->connected (fuse_chan struct not present in this kernel) This fixes this race: - thread a: io_uring_enter -> register sqe -> fuse_uring_create_ring_ent -> allocate ent but doesn't grab queue_ref yet - thread b: fuse_conn_destroy() -> fuse_chan_abort() -> fuse_uring_abort() is a no-op due to queue ref being 0 - thread a: grabs the queue_ref, queue_ref is now 1, rest of fuse_uring_do_register() logic executes - thread b: fuse_chan_abort() returns, fuse_chan_wait_aborted() now runs and calls "wait_event(ring->stop_waitq, atomic_read(&ring->queue_refs) == 0);" The abort/unmount thread will hang indefinitely in unkillable state as nothing will decrement queue_refs or wake stop_waitq, and the ring, queue, and ent are leaked. Fix this by checking fch->connected under fch->lock after the created ent has grabbed a ref count on the queue. This ensures that in the scenario above, it is guaranteed that we either release the queue ref and wake up stop_waitq (in case fuse_chan_wait_aborted() is already waiting) in fuse_uring_do_register() when we detect !fch->connected, or if the connection is aborted after the check, it is guaranteed that the async teardown worker will be running in the background cleaning up ents and decrementing the ent's ref on the queue, which will unblock the eventual queue and ring teardown. Fixes: 24fe962 ("fuse: {io-uring} Handle SQEs - register commands") Cc: stable@vger.kernel.org Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 952b5d3) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Joanne Koong <joannelkoong@gmail.com> commit c146284 upstream-diff | fch->lock/fch->connected changed to fc->lock/fc->connected in fuse_uring_do_register() already applied in 703224b. Only the fuse_uring_create() hunk is new. Check fc->connected under fc->lock in fuse_uring_create() before attaching a new ring. Without this, a race between fuse_uring_create() and fuse_conn_destroy() can result in the ring, queue, and fpq.processing table being created after fuse_uring_abort() has already run, leading to unnecessary allocation and teardown. These are eventually cleaned up by fuse_uring_destruct() but will linger until the process exits, even with the connection aborted. Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit c146284) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 cve CVE-2026-64263 RFE: FUSE_IO_URING commit-author Joanne Koong <joannelkoong@gmail.com> commit 198f45e upstream-diff | io_uring_cmd_done() uses 4 args (res2=0) vs upstream 3 args. list_move used instead of list_move_tail. fuse_uring_cancel() moves entries that are available (these have no reqs attached) to the ent_in_userspace list. ent_list_request_expired() checks the first entry on ent_in_userspace and dereferences ent->fuse_req unconditionally, which will crash on a cancelled entry that was moved to this list. Fix this by freeing the entry and dropping queue_refs directly in fuse_uring_cancel(). This is safe because cancel is the cancel handler itself - after io_uring_cmd_done(), no more cancels will be dispatched for this command, and teardown serializes with cancel via queue->lock. Since cancel now decrements queue_refs, fuse_uring_abort() must no longer gate fuse_uring_abort_end_requests() on queue_refs > 0, as cancelled entries may have already dropped queue_refs while requests are still queued. Remove the gate so abort always flushes requests and stops queues. Reported-by: Heechan Kang <gganji11@naver.com> Tested-by: Heechan Kang <gganji11@naver.com> Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Fixes: 4fea593 ("fuse: optimize over-io-uring request expiration check") Cc: stable@vger.kernel.org Suggested-by: Jian Huang Li <ali@ddn.com> Suggested-by: Horst Birthelmer <horst@birthelmer.de> Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 198f45e) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 cve CVE-2026-64262 RFE: FUSE_IO_URING commit-author Chris Mason <clm@meta.com> commit bea4fe9 upstream-diff | fuse_uring_send_in_task has different signature (missing io_tw_req/io_tw_token_t API in this kernel) io_uring_cmd_done() call corrected to pass 4 args (res2=0 was missing in upstream adaptation) When io_uring delivers task work with tw.cancel set (PF_EXITING, PF_KTHREAD fallback, or percpu_ref_is_dying on the ring context), fuse_uring_send_in_task() takes the cancel branch, assigns -ECANCELED, and falls through to fuse_uring_send(). That path only flips the entry to FRRS_USERSPACE and completes the io_uring cmd; it never discharges the ring entry's owning reference to the fuse_req that fuse_uring_add_req_to_ring_ent() handed it at dispatch time. fuse_uring_send_in_task() tw.cancel == true err = -ECANCELED fuse_uring_send(ent, cmd, err, issue_flags) ent->state = FRRS_USERSPACE list_move(&ent->list, &queue->ent_in_userspace) ent->cmd = NULL io_uring_cmd_done(-ECANCELED) /* ent->fuse_req still set, req still hashed */ The fuse_req stays linked on fpq->processing[hash] and fuse_request_end() is never invoked. The originating syscall thread blocks in D-state in request_wait_answer() until fuse_abort_conn() runs, which can be the entire connection lifetime. For FR_BACKGROUND requests fc->num_background is never decremented either, so repeated cancels inflate the counter until max_background is hit and all later background ops stall. tw.cancel does not imply a connection abort (e.g. a single io_uring worker thread exits while the fuse connection stays up), so this cannot be left for fuse_abort_conn() to clean up. Ending the req but still routing the entry through fuse_uring_send() is not enough: that leaves a req-less entry on ent_in_userspace, and ent_list_request_expired() dereferences ent->fuse_req unconditionally on the head of that list, which would then NULL-deref. Fix the cancel branch to release the entry directly. Remove it from the queue, complete the io_uring cmd, end the fuse_req, free the entry, and drop its queue_refs (waking the teardown waiter if it was the last). Fixes: c2c9af9 ("fuse: Allow to queue fg requests through io-uring") Cc: stable@vger.kernel.org Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Assisted-by: kres (claude-opus-4-7) Signed-off-by: Chris Mason <clm@meta.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit bea4fe9) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 cve CVE-2026-64261 RFE: FUSE_IO_URING commit-author Bernd Schubert <bernd@bsbernd.com> commit d351da7 upstream-diff | ring->fc used instead of ring->chan->conn fuse_uring_async_stop_queues() might run when the last reference on ring->queue_refs was already dropped. In order to avoid an early destruction a reference on struct fuse_conn is now taken before starting fuse_uring_async_stop_queues() and that reference is only released when that delayed work queue terminates. Fixes: 4a9bfb9 ("fuse: {io-uring} Handle teardown of ring entries") Cc: stable@kernel.org # 6.14 Reported-by: Berkant Koc <me@berkoc.com> Signed-off-by: Bernd Schubert <bernd@bsbernd.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit d351da7) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
…lock jira SECO-478 cve CVE-2026-64260 RFE: FUSE_IO_URING commit-author Bernd Schubert <bernd@bsbernd.com> commit b70a3ac upstream-diff | ring->fc used instead of ring->chan->conn There are several readers of queue->stopped that check the value under lock, but fuse_uring_commit_fetch() did not and actually the value was not set under the lock in fuse_uring_abort_end_requests() either. Especially in fuse_uring_commit_fetch it is important to check under a lock, because due to races 'struct fuse_req' might be freed with fuse_request_end, but another thread/cpu might already do teardown work. Cc: stable@kernel.org # 6.14 Fixes: 4a9bfb9 ("fuse: {io-uring} Handle teardown of ring entries") Reported-by: Berkant Koc <me@berkoc.com> Reported-by: xlabai <xlabai@tencent.com> Signed-off-by: Bernd Schubert <bernd@bsbernd.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit b70a3ac) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 cve CVE-2026-64259 RFE: FUSE_IO_URING commit-author Bernd Schubert <bernd@bsbernd.com> commit 1efd3d4 upstream-diff | list_move used instead of list_move_tail and io_uring_cmd_done has extra arg (older API in this kernel) Bad userspace might try to trick us and send commit SQEs request unique / commit-id of requests that are not even send to fuse-server (io_uring_cmd_done() not called) yet. fuse_uring_commit_fetch() ends the fuse request when the ring entry has a wrong state, but that could have caused a use-after-free with the memcpy operations in fuse_uring_send_in_task(). In order to avoid such races the call of fuse_uring_add_to_pq() is moved after the copy operations and just before completing the io-uring request - malicious userspace cannot find the request anymore until all prepration work in fuse-client/kernel is completed. This also moves fuse_uring_add_to_pq() a bit up in the code to avoid a forward declaration. Also not with a preparation commit, to make it easier to back port to older kernels. Reported-by: xlabai <xlabai@tencent.com> Reported-by: Berkant Koc <me@berkoc.com> Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support") Cc: stable@kernel.org # 6.14 Signed-off-by: Bernd Schubert <bernd@bsbernd.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 1efd3d4) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
…ULL deref jira SECO-478 cve CVE-2026-64258 RFE: FUSE_IO_URING commit-author Joanne Koong <joannelkoong@gmail.com> commit 1c57a69 If a copy into the userspace ring buffer fails, a request will be terminated and fuse_uring_req_end() will set ent->fuse_req to NULL but it will leave the entry on ent_w_req_queue in FRRS_FUSE_REQ state. This can lead to a NULL deref if the request expiration logic scans ent_w_req_queue in the window before the entry is moved off it. Fix this by taking the entry off ent_w_req_queue and changing its state from FRRS_FUSE_REQ to FRRS_INVALID before terminating the request. Fixes: 4fea593 ("fuse: optimize over-io-uring request expiration check") Cc: stable@kernel.org Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 1c57a69) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Joanne Koong <joannelkoong@gmail.com> commit 31da059 upstream-diff | fuse_copy_init uses int write vs bool write in this kernel When a background request completes via the io_uring path, the background queue gets flushed to dispatch pending background requests, but this is done before the connection-level background counters (fc->num_background, fc->active_background) are properly accounted, which may reduce effective queue depth to one. The connection-level counters are decremented in fuse_request_end(), but flush_bg_queue() flushes the /dev/fuse path queue (fc->bg_queue), not the io_uring per-queue bg one, which means pending uring background requests on the queue are never dispatched in this path. Fix this by accounting the connection-level background counters first before flushing the queue's background queue. Since fuse_request_bg_finish() clears FR_BACKGROUND, fuse_request_end() will skip the background cleanup branch entirely, which avoids any double-decrements; it will call the wake_up(&req->waitq) branch but this is effectively a no-op as background requests have no waiters on req->waitq. Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Fixes: 857b026 ("fuse: Allow to queue bg requests through io-uring") Cc: stable@vger.kernel.org Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 31da059) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Zhenghang Xiao <kipreyyy@gmail.com> commit 7d87a5a fuse_uring_commit_fetch() error path called fuse_request_end(req) without clearing ent->fuse_req when fuse_ring_ent_set_commit() fails. The still-pending fuse_uring_send_in_task() task-work later dereferences the dangling pointer through fuse_uring_prepare_send(), causing a use-after-free. End the request with fuse_uring_req_end(), which handles all conditions already. Annotation/edition by Bernd: The UAF should be fixed by other means already and actually has to be avoided that way. Just checking for ent->fuse_req == NULL in fuse_uring_send_in_task() would be prone to race conditions, because if malicious userspace would commit requests that have passed the NULL check, but are in doing args copy, it would still trigger a use-after-free. Setting ent->fuse_req = NULL in fuse_uring_commit_fetch() still makes sense, though. Reported-by: Shuvam Pandey <shuvampandey1@gmail.com> Reported-by: Berkant Koc <me@berkoc.com> Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com> Signed-off-by: Bernd Schubert <bernd@bsbernd.com> Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 7d87a5a) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING Enable FUSE io-uring support in all configs that have both prerequisites (CONFIG_FUSE_FS=m and CONFIG_IO_URING=y): x86_64, aarch64, ppc64le, and s390x across all variants (debug, rt, 64k). Skipped configs lacking prerequisites: - kernel-riscv64-*.config (no CONFIG_FUSE_FS or CONFIG_IO_URING) - kernel-s390x-zfcpdump-rhel.config (CONFIG_FUSE_FS is not set) The feature is gated at runtime by the enable_uring module parameter which defaults to disabled. Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
…ectl jira SECO-478 RFE: FUSE_IO_URING commit-author Chen Linxuan <chenlinxuan@uniontech.com> commit 1a7b137 This patch add a simple functional test for the 'abort' file in fusectlfs (/sys/fs/fuse/connections/ID/abort). A simple fuse daemon is added for testing. Signed-off-by: Chen Linxuan <chenlinxuan@uniontech.com> Acked-by: Shuah Khan <skhan@linuxfoundation.org> Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 1a7b137) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
On systems with only libfuse3-devel installed (no libfuse2-devel), fuse_mnt.c fails to compile because fuse3 requires API version 30+. Update fuse_mnt.c from FUSE API version 26 to 31: - getattr, truncate: add struct fuse_file_info * parameter - readdir: add enum fuse_readdir_flags parameter - filler calls: add flags argument Also update the Makefile to try pkg-config fuse3 as a fallback when pkg-config fuse is not available. Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478 RFE: FUSE_IO_URING commit-author Amir Goldstein <amir73il@gmail.com> commit 9acb102 upstream-diff | kselftest_harness.h include uses relative path (../../kselftest_harness.h) because commit e6fbd17 ("selftests: complete kselftest include centralization") is not present in this tree. A FUSE mount that does not negotiate FUSE_POSIX_ACL initialises every inode with i_acl = i_default_acl = ACL_DONT_CACHE. When a fresh stat is needed (e.g. AT_STATX_FORCE_SYNC), fuse_update_get_attr() calls forget_all_cached_acls() before issuing FUSE_GETATTR. On an unfixed kernel, __forget_cached_acl() replaces ACL_DONT_CACHE with ACL_NOT_CACHED, inadvertently enabling the kernel ACL cache for that inode. This test validates the fix that preserves ACL_DONT_CACHE state in forget_cached_acl(). Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org> (cherry picked from commit 9acb102) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
Add a kselftest for the FUSE io-uring request dispatch path. A
minimal in-memory FUSE daemon runs in a thread, negotiates
FUSE_OVER_IO_URING during FUSE_INIT, and handles requests through
FUSE_IO_URING_CMD_REGISTER / FUSE_IO_URING_CMD_COMMIT_AND_FETCH.
An atomic counter verifies requests are served through io_uring.
Test cases:
- read_file: read and verify file content
- write_and_readback: write data, read it back, compare
- readdir: list directory, verify entries
- stat_files: stat root and file, verify attributes
- concurrent_io: 4 threads doing interleaved reads and writes
- requests_via_uring: per-operation verification that read, write,
readdir, and stat each produce io_uring requests
- sustained_io: write 256KB in 4KB chunks, read back, verify pattern
- crash_recovery: fork daemon, SIGKILL with active I/O, verify
kernel health
- abort_before_ring_ready: negotiate io_uring but never register
entries, abort connection, verify no deadlock or leak
Tests SKIP when prerequisites are not met (no root, io_uring
disabled, enable_uring != Y).
Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
Collaborator
|
Results from attached test script: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR has been automatically created after successful completion of all CI stages.
Commit Message(s)
Test Results
✅ Build Stage
✅ Boot Verification
✅ Kernel Selftests
✅ LTP Results
🤖 This PR was automatically generated by GitHub Actions
Run ID: 32144535161