Re: [PATCH] ublk: configure io buffer before taking uring_cmd

Caleb Sander Mateos <[email protected]>
Newsgroups org.kernel.vger.linux-block
Message-ID <CADUfDZq1djzvp0rmG48jwavAZGWAZ4Fe3BUCCFxLMUPewbcH5Q@mail.gmail.com>
On Fri, Jul 24, 2026 at 3:05 AM Yang Xiuwei <[email protected]> wrote:
>
> With UBLK_F_AUTO_BUF_REG, ublk_config_io_buf() may fail on invalid
> auto buffer register data in sqe->addr. Calling ublk_fill_io_cmd()
> first leaves UBLK_IO_FLAG_ACTIVE set while io_uring has already
> completed the uring_cmd. The tag can no longer be fetched, and
> device teardown may hang or complete a stale command.
>
> Fixes: 52460dda3a77 ("ublk: move auto buffer register handling into one dedicated helper")
> Signed-off-by: Yang Xiuwei <[email protected]>
> ---
>  drivers/block/ublk_drv.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
> index c2c11f2a01e7..d932a4026031 100644
> --- a/drivers/block/ublk_drv.c
> +++ b/drivers/block/ublk_drv.c
> @@ -3295,9 +3295,9 @@ static int ublk_fetch(struct io_uring_cmd *cmd, struct ublk_device *ub,
>          * FETCH, so it is fine even for IO_URING_F_NONBLOCK.
>          */
>         mutex_lock(&ub->mutex);
> -       ret = __ublk_fetch(cmd, ub, io, q_id);
> +       ret = ublk_config_io_buf(ub, io, cmd, buf_addr, NULL);
>         if (!ret)
> -               ret = ublk_config_io_buf(ub, io, cmd, buf_addr, NULL);
> +               ret = __ublk_fetch(cmd, ub, io, q_id);

I'm not sure this ordering works either. __ublk_fetch() is responsible
for checking that the I/O is in a valid state to fetch (device not yet
started, I/O not yet fetched). It wouldn't be safe to overwrite
io->buf before this check. Probably it would make sense to perform the
sqe->addr validation before calling __ublk_fetch() and then make
ublk_config_io_buf() infallible.

Best,
Caleb


>         if (!ret)
>                 ublk_mark_io_ready(ub, q_id, io);
>         mutex_unlock(&ub->mutex);
> @@ -3447,19 +3447,18 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
>                 if (ret)
>                         goto out;
>                 io->res = result;
> -               req = ublk_fill_io_cmd(io, cmd);
>                 ret = ublk_config_io_buf(ub, io, cmd, addr, &buf_idx);
>                 if (buf_idx != UBLK_INVALID_BUF_IDX)
>                         io_buffer_unregister_bvec(cmd, buf_idx, issue_flags);
> +               if (ret)
> +                       goto out;
> +               req = ublk_fill_io_cmd(io, cmd);
>                 compl = ublk_need_complete_req(ub, io);
>
>                 if (req_op(req) == REQ_OP_ZONE_APPEND)
>                         req->__sector = addr;
>                 if (compl)
>                         __ublk_complete_rq(req, io, ublk_dev_need_map_io(ub), NULL);
> -
> -               if (ret)
> -                       goto out;
>                 break;
>         case UBLK_IO_NEED_GET_DATA:
>                 /*
> --
> 2.25.1
>
>
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.