Re: [PATCH] scsi: bsg: copy uring_cmd payload to prevent double-fetch from shared SQE

From: Jens Axboe

Date: Wed May 27 2026 - 12:10:19 EST


On 5/27/26 4:59 AM, Rahul Chandelkar wrote:
> scsi_bsg_uring_cmd() and scsi_bsg_map_user_buffer() read bsg_uring_cmd
> fields directly from the shared mmap'd io_uring submission ring via
> io_uring_sqe128_cmd(). On the inline execution path, io_uring has not
> yet copied the SQE to kernel memory, so a concurrent userspace thread
> can modify fields between reads.
>
> cmd->request_len is read for the bounds check, for the cmd_len
> assignment, and for the copy_from_user length. A racing thread can
> change request_len between the bounds check (passes with <= 32) and
> copy_from_user (uses the enlarged value), overflowing the 32-byte
> scmd->cmnd[] buffer into subsequent struct scsi_cmnd fields.
>
> scsi_bsg_map_user_buffer() independently re-derives its cmd pointer
> from the same shared SQE, re-reading dout_xfer_len, din_xfer_len,
> dout_xferp, and din_xferp, enabling direction confusion and buffer
> length races.
>
> Copy struct bsg_uring_cmd to a stack-local variable before use in both
> functions. The pointer variable 'cmd' is redirected to the local copy
> so the rest of each function is unchanged.
>
> Tested with KASAN on QEMU (virtio-scsi, 2 vCPUs). Without this fix,
> a two-thread race produces:
>
> BUG: KASAN: wild-memory-access in scsi_queue_rq+0x4a3/0x58a0
> Write of size 96 at addr dead000000001000 by task poc/67
> Call Trace:
> kasan_report+0xce/0x100
> __asan_memset+0x23/0x50
> scsi_queue_rq+0x4a3/0x58a0
> scsi_bsg_uring_cmd+0x942/0x1570
> io_uring_cmd+0x2f6/0x950
> io_issue_sqe+0xe5/0x22d0

I don't think this is the right way to fix it, ->sqe should've been
stable upfront if this ends up happening. Can you share your poc with
me? Your trace has been trimmed down way too much to be useful.

--
Jens Axboe