Re: [PATCH v5] fuse: clear ent->fuse_req in commit_fetch error path

From: Joanne Koong

Date: Mon Jun 15 2026 - 07:59:17 EST


On Mon, Jun 15, 2026 at 6:26 AM Bernd Schubert via B4 Relay
<devnull+bernd.bsbernd.com@xxxxxxxxxx> wrote:
>
> From: Zhenghang Xiao <kipreyyy@xxxxxxxxx>
>
> 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@xxxxxxxxx>
> Reported-by: Berkant Koc <me@xxxxxxxxxx>
> Signed-off-by: Zhenghang Xiao <kipreyyy@xxxxxxxxx>
> Signed-off-by: Bernd Schubert <bernd@xxxxxxxxxxx>
> ---
> This is to fix race conditions reported by Berkant and Zhenghang.
>
> Changes in v5:
> - Rebased against Miklos' for-next branch - all except one patch already
> picked up
> - Use fuse_uring_req_end() instead of hand coding what it does
> ---
> fs/fuse/dev_uring.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c
> index ba5edf5d01b3..77c8cec43d9c 100644
> --- a/fs/fuse/dev_uring.c
> +++ b/fs/fuse/dev_uring.c
> @@ -1003,9 +1003,7 @@ static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags,
> pr_info_ratelimited("qid=%d commit_id %llu state %d",
> queue->qid, commit_id, ent->state);
> spin_unlock(&queue->lock);
> - req->out.h.error = err;
> - clear_bit(FR_SENT, &req->flags);
> - fuse_request_end(req);
> + fuse_uring_req_end(ent, req, err);
> return err;
> }
>
>
> ---
> base-commit: bb43b4c7ea2a8265141aa93240f3f0ca71d85c0e
> change-id: 20260518-fuse-io-uring-race-fixes-59760420d2ae
>
> Best regards,
> --
> Bernd Schubert <bernd@xxxxxxxxxxx>
>

Reviewed-by: Joanne Koong <joannelkoong@xxxxxxxxx>