Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: Niklas Cassel <cassel@kernel.org>
To: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
	"Martin K. Petersen" <mkp@kernel.org>
Cc: linux-scsi@vger.kernel.org, Damien Le Moal <dlemoal@kernel.org>,
	John Garry <john.garry@linux.dev>,
	Niklas Cassel <cassel@kernel.org>
Subject: [PATCH v10 05/12] scsi: scsi_debug: Avoid 32-bit overflow in WRITE SCATTERED offsets
Date: Mon, 28 Sep 2026 09:21:08 +0200	[thread overview]
Message-ID: <20260928072102.725566-19-cassel@kernel.org> (raw)
In-Reply-To: <20260928072102.725566-14-cassel@kernel.org>

resp_write_scat() computes the length of an LBA range in bytes as a
32-bit product, num_by = num * lb_size, and adds it to sg_off, the
32-bit offset of the next range in the data-out buffer.
check_device_access_params() limits num to the number of sectors in the
store, so the product wraps once the store is 4 GiB or larger, and
sg_off wraps with it. The ranges that follow are then written from the
wrong offset in the buffer.

Make num_by and sg_off 64-bit. do_device_access() takes a 32-bit
offset, so pass it sg_off capped at U32_MAX: a data-out buffer is at
most U32_MAX bytes, so a capped offset is still at or past its end and
nothing is copied.

Assisted-by: LLM
Fixes: 481b5e5c7949 ("scsi: scsi_debug: add resp_write_scat function")
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
Tested with:

  modprobe scsi_debug sector_size=512 dev_size_mb=4097

in a guest with 8 GiB of memory, issuing a WRITE SCATTERED (16) through
SG_IO with two LBA range descriptors: 8388608 blocks at LBA 0, which is
exactly 4 GiB, and 8 blocks at LBA 8388608. The 8704 byte buffer holds
the parameter list and 16 blocks, so the first range consumes all of it.
Before this patch the offset wrapped, and the second range was written
with the data of the first; after it the second range is left as it
was.
---
 drivers/scsi/scsi_debug.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index b64ae3ad300d..8f9d54269dce 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -5197,7 +5197,8 @@ static int resp_write_scat(struct scsi_cmnd *scp,
 	struct sdeb_store_info *sip = devip2sip(devip, true);
 	u8 wrprotect;
 	u16 lbdof, num_lrd, k;
-	u32 num, num_by, bt_len, lbdof_blen, sg_off, cum_lb;
+	u32 num, bt_len, lbdof_blen, cum_lb;
+	u64 num_by, sg_off;
 	u32 lb_size = sdebug_sector_size;
 	u32 ei_lba;
 	u64 lba;
@@ -5273,14 +5274,14 @@ static int resp_write_scat(struct scsi_cmnd *scp,
 		num = get_unaligned_be32(up + 8);
 		if (sdebug_verbose)
 			sdev_printk(KERN_INFO, scp->device,
-				"%s: k=%d  LBA=0x%llx num=%u  sg_off=%u\n",
+				"%s: k=%d  LBA=0x%llx num=%u  sg_off=%llu\n",
 				my_name, k, lba, num, sg_off);
 		if (num == 0)
 			continue;
 		ret = check_device_access_params(scp, lba, num, true);
 		if (ret)
 			goto err_out_unlock;
-		num_by = num * lb_size;
+		num_by = (u64)num * lb_size;
 		ei_lba = is_16 ? 0 : get_unaligned_be32(up + 12);
 
 		if ((cum_lb + num) > bt_len) {
@@ -5311,7 +5312,8 @@ static int resp_write_scat(struct scsi_cmnd *scp,
 		 * Write ranges atomically to keep as close to pre-atomic
 		 * writes behaviour as possible.
 		 */
-		ret = do_device_access(sip, scp, sg_off, lba, num, group, true, true);
+		ret = do_device_access(sip, scp, min_t(u64, sg_off, U32_MAX), lba,
+				       num, group, true, true);
 		/* If ZBC zone then bump its write pointer */
 		if (sdebug_dev_is_zoned(devip))
 			zbc_inc_wp(devip, lba, num);
@@ -5322,7 +5324,7 @@ static int resp_write_scat(struct scsi_cmnd *scp,
 			goto err_out_unlock;
 		} else if (unlikely(sdebug_verbose && (ret < num_by)))
 			sdev_printk(KERN_INFO, scp->device,
-			    "%s: write: cdb indicated=%u, IO sent=%d bytes\n",
+			    "%s: write: cdb indicated=%llu, IO sent=%d bytes\n",
 			    my_name, num_by, ret);
 
 		if (unlikely((sdebug_opts & SDEBUG_OPT_RECOV_DIF_DIX) &&
-- 
2.55.0


  parent reply	other threads:[~2026-09-28  7:21 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28  7:21 [PATCH v10 00/12] scsi: scsi_debug: fix zoned write validation Niklas Cassel
2026-09-28  7:21 ` [PATCH v10 01/12] scsi: scsi_debug: Refuse a zoned device with a non-zero lowest aligned LBA Niklas Cassel
2026-09-28  7:21 ` [PATCH v10 02/12] scsi: scsi_debug: Make atomic writes and ZBC emulation mutually exclusive Niklas Cassel
2026-09-28  7:21 ` [PATCH v10 03/12] scsi: scsi_debug: Take the zone metadata lock before the data lock Niklas Cassel
2026-09-28  7:21 ` [PATCH v10 04/12] scsi: scsi_debug: Evaluate scsi_debug_lbp() only once Niklas Cassel
2026-09-28  7:21 ` Niklas Cassel [this message]
2026-09-28  7:39   ` [PATCH v10 05/12] scsi: scsi_debug: Avoid 32-bit overflow in WRITE SCATTERED offsets sashiko-bot
2026-09-28  7:21 ` [PATCH v10 06/12] scsi: scsi_debug: Report the residual of a write Niklas Cassel
2026-09-28  8:18   ` Damien Le Moal
2026-09-28  7:21 ` [PATCH v10 07/12] scsi: scsi_debug: Enforce physical block alignment of zoned writes Niklas Cassel
2026-09-28  7:21 ` [PATCH v10 08/12] scsi: scsi_debug: Do not write a partial physical block to a zoned device Niklas Cassel
2026-09-28  7:21 ` [PATCH v10 09/12] scsi: scsi_debug: Advance the write pointer over the data written Niklas Cassel
2026-09-28  7:21 ` [PATCH v10 10/12] scsi: scsi_debug: Refuse a short WRITE ATOMIC (16) before writing it Niklas Cassel
2026-09-28  7:21 ` [PATCH v10 11/12] scsi: scsi_debug: Map the region written by WRITE ATOMIC (16) Niklas Cassel
2026-09-28  7:21 ` [PATCH v10 12/12] scsi: scsi_debug: Validate the access parameters of " Niklas Cassel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260928072102.725566-19-cassel@kernel.org \
    --to=cassel@kernel.org \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=dlemoal@kernel.org \
    --cc=john.garry@linux.dev \
    --cc=linux-scsi@vger.kernel.org \
    --cc=mkp@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox