Re: [RFC PATCH] io_uring/cmd: don't skip completion for a non-armed multishot uring_cmd

Vasileios Almpanis <[email protected]>
Newsgroups org.kernel.vger.io-uring,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Hi everyone,

Just a gentle ping on this patch.

The issue is syzbot-reproduced and the proposed fix has been run with 
#syz test.
The patch addresses the leak in the core |io_uring_cmd()|path rather than
relying on individual providers to handle |IORING_URING_CMD_MULTISHOT|.

Could someone take a look when you get a chance?

Thanks,
Vasileios


On 8/11/26 10:42 PM, Vasileios Almpanis wrote:
> io_uring_cmd() treats any uring_cmd carrying IORING_URING_CMD_MULTISHOT
> that returns >= 0 as "multishot armed, completion deferred" and returns
> IOU_ISSUE_SKIP_COMPLETE, expecting the provider to complete the request
> later. But the flag is user-controlled and validated only against buffer
> select, not against provider capability. A ->uring_cmd() handler that
> does not implement multishot and returns a normal >= 0 result then has
> its request skipped and never completed, leaking the io_kiocb and its
> io_async_cmd:
>
>    BUG: memory leak
>    unreferenced object (size 248):
>      kmem_cache_alloc_bulk_noprof+0x272/0x3f0
>      __io_alloc_req_refill+0x4a/0x150
>      io_submit_sqes.cold+0x16e/0x20b
>      __do_sys_io_uring_enter+0x56d/0xd60
>
> syzbot hit this via ublk UBLK_U_CMD_ADD_DEV, but it is kernel-wide: the
> same leak reproduces with SOCKET_URING_OP_SIOCINQ on any socket fd, which
> returns the queued byte count and never inspects cmd->flags. No in-tree
> provider of multishot actually returns >= 0. Both io_cmd_poll_multishot()
> and ublk_handle_batch_fetch_cmd return -EIOCBQUEUED,
>
> Only skip completion when the command is really multishot, i.e.
> REQ_F_APOLL_MULTISHOT is set. Otherwise fall through and complete the
> request normally with its result.
>
> Fixes: 620a50c92700 ("io_uring: uring_cmd: add multishot support")
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=a4ccdd7ebf452e4d4701
> Tested-by: [email protected]
> Signed-off-by: Vasileios Almpanis <[email protected]>
> ---
> Questions / Notes:
> - I put this in the core io_uring_cmd() rather than in provider specific
>    code because the leak is independent of the provider. From my research
>    so far no ->uring_cmd() rejects IORING_URING_CMD_MULTISHOT, they just
>    ignore it. The flag is only validated against buffer-select in
>    io_uring_cmd_prep(). So any handler that returns a plain >= 0 result
>    with the user-set flag leaks.
> - Instead of checking if it has been really armed should we just drop
>    the >= 0 check? The in-tree code that supports multishot returns
>    -EIOCBQUEUED from what I have seen so far.
> ---
>   io_uring/uring_cmd.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c
> index c14c22cff49e..a2899a852879 100644
> --- a/io_uring/uring_cmd.c
> +++ b/io_uring/uring_cmd.c
> @@ -269,7 +269,8 @@ int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags)
>   	}
>   
>   	ret = file->f_op->uring_cmd(ioucmd, issue_flags);
> -	if (ioucmd->flags & IORING_URING_CMD_MULTISHOT) {
> +	if ((ioucmd->flags & IORING_URING_CMD_MULTISHOT) &&
> +	    (req->flags & REQ_F_APOLL_MULTISHOT)) {
>   		if (ret >= 0)
>   			return IOU_ISSUE_SKIP_COMPLETE;
>   	}
>
> ---
> base-commit: d58772d8520c7ef247c4b95c9bd76d3a25da9ff5
> change-id: 20260811-io_uring-169337c74617
>
> Best regards,
> --
> Vasileios Almpanis <[email protected]>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.