linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Christoph Hellwig" <hch@lst.de>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH] scsi_debug: add support to corrupt data and/or reftag
Date: Wed, 19 Aug 2026 07:13:25 +0000	[thread overview]
Message-ID: <20260819071326.456301F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260819065850.1358861-2-hch@lst.de>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

New issues:
- [High] Unbounded nested loops in `corrupt_lbas()` executed with preemption disabled allow users to cause CPU lockups.
- [High] Unconditional dereference of `sip` in `corrupt_lbas()` when initialized with fake I/O (`fake_rw=1`).
- [Medium] Flawed map state validation in `corrupt_lbas()` rejects valid wrapping corruption requests.

Pre-existing issues:
- [High] Pre-existing out-of-bounds array access in `map_state()` when using large virtual LBAs.
- [High] Toggling `fake_rw` from 1 to 0 at runtime causes a pre-existing NULL pointer dereference in LBP operations.
--

--- Patch [1]: [PATCH] scsi_debug: add support to corrupt data and/or reftag ---
commit b674d4afbf6311bc89a7d69aaa16a3947e8d3546
Author: Christoph Hellwig <hch@lst.de>
scsi_debug: add support to corrupt data and/or reftag

Add a new debugfs file to inject corruptions of the data and/or reftag.
This will be used to detect that protection information and/or file
system checksumming can detect random bit errors or misplaced writes.

> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index 3346562275f80..8750e07759306 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c

[ ... ]

> @@ -4862,6 +4952,77 @@ static int resp_write_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
>  	return 0;
>  }
>  
> +static int corrupt_lbas(struct sdebug_dev_info *devip, u64 lba, u32 num,
> +		u32 nr_bit_errors, s32 reftag_adjust)
> +{
> +	struct sdeb_store_info *sip = devip2sip(devip, false);
> +	bool meta_data_locked = false;
> +	u8 *fsp = sip->storep;

[Severity: High]
Does this unconditionally dereference sip if devip2sip() returns NULL?

If the scsi_debug module is loaded or toggled with fake_rw=1, devip2sip()
explicitly returns NULL. The sip->storep assignment then dereferences it
before any validation occurs, which will cause a kernel panic.

> +	u32 block, num_mapped, b, i;
> +	int error = 0;
> +
> +	if (sdebug_dev_is_zoned(devip) ||
> +	    sdebug_dix ||
> +	    scsi_debug_lbp())  {
> +		sdeb_meta_write_lock(sip);
> +		meta_data_locked = true;
> +	}
> +
> +	if (num > sdebug_capacity || lba > sdebug_capacity - num) {
> +		pr_err("logical blocks out of bounds: %llu:%u", lba, num);
> +		error = -EINVAL;
> +		goto out_unlock;
> +	}
> +
> +	if (scsi_debug_lbp() &&
> +	    (!map_state(sip, lba, &num_mapped) || num > num_mapped)) {

[Severity: High]
This is a pre-existing issue, but can map_state() perform an out-of-bounds
array access when called with large virtual LBAs?

If sdebug_virtual_gb is configured, sdebug_capacity exceeds the physical
sdebug_store_sectors. A command passing a large LBA generates an index
larger than map_size:

drivers/scsi/scsi_debug.c:map_state() {
    ...
    index = lba_to_map_index(lba);
    mapped = test_bit(index, sip->map_storep);
    ...
}

This causes test_bit and subsequent bit operations to access memory outside
the allocated sip->map_storep array.

[Severity: Medium]
Does this check incorrectly reject valid corruption requests that cross the
physical storage boundary?

If a user requests corruption across the physical store boundary (for example,
an lba near sdebug_store_sectors with a num crossing it), map_state() limits
the returned contiguous blocks to the physical boundary:

drivers/scsi/scsi_debug.c:map_state() {
    ...
    end = min_t(sector_t, sdebug_store_sectors, map_index_to_lba(next));
    *num = end - lba;
    ...
}

This causes the num > num_mapped condition to trigger and abort the request,
even though the underlying data loops correctly use div_u64_rem to wrap
around the physical bounds.

[Severity: High]
This is a pre-existing issue, but does toggling fake_rw from 1 to 0 at
runtime cause a NULL pointer dereference in LBP operations?

If fake_rw is toggled from 1 to 0 via sysfs, fake_rw_store() calls
sdebug_add_store() before updating sdebug_fake_rw to 0:

drivers/scsi/scsi_debug.c:fake_rw_store() {
    ...
    idx = sdebug_add_store();
    ...
    sdebug_fake_rw = n;
    ...
}

Inside sdebug_add_store(), scsi_debug_lbp() returns false because
sdebug_fake_rw is still 1, so sip->map_storep remains unallocated. Once
the transition completes, fake_rw is 0 and LBP becomes active. Any
subsequent command using LBP calls map_state(), which crashes when
dereferencing the NULL sip->map_storep.

> +		pr_err("can't modify unmapped logical blocks: %llu:%u",
> +			lba, num);
> +		error = -EINVAL;
> +		goto out_unlock;
> +	}
> +
> +	/*
> +	 * For each possible bit error, flip the same bit in each corrupted
> +	 * block to simulate repeated patterns like errors in cables.
> +	 */
> +	sdeb_data_lock(sip, false);
> +	for (b = 0; b < nr_bit_errors; b++) {
> +		unsigned int bit;
> +
> +		bit = get_random_u32_below(sdebug_sector_size * BITS_PER_BYTE);
> +		pr_info("flipping bit %u in LBAs %llu:%llu\n",
> +				bit, lba, lba + num - 1);
> +
> +		div_u64_rem(lba, sdebug_store_sectors, &block);
> +		for (i = 0; i < num; i++) {

[Severity: High]
Can these unbounded nested loops cause a CPU lockup since they run with
preemption disabled?

A user can write large values for num and nr_bit_errors into the corrupt
debugfs file. The sdeb_data_lock() function calls read_lock(), which
disables preemption. The function then enters these loops, potentially
stalling the CPU for an extended period of time if the inputs are large.

> +			u8 *p = fsp + (block * sdebug_sector_size);
> +
> +			sdeb_data_sector_lock(sip, true);
> +			p[bit / BITS_PER_BYTE] ^= (1 << (bit % BITS_PER_BYTE));
> +			sdeb_data_sector_unlock(sip, true);
> +			if (++block >= sdebug_store_sectors)
> +				block = 0;
> +		}
> +	}

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260819065850.1358861-2-hch@lst.de?part=1

  reply	other threads:[~2026-08-19  7:13 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-19  6:58 scsi_debug: add support to corrupt data and/or reftag v2 Christoph Hellwig
2026-08-19  6:58 ` [PATCH] scsi_debug: add support to corrupt data and/or reftag Christoph Hellwig
2026-08-19  7:13   ` sashiko-bot [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-07-23 14:21 Christoph Hellwig
2026-07-23 14:37 ` sashiko-bot

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=20260819071326.456301F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=hch@lst.de \
    --cc=linux-scsi@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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;
as well as URLs for NNTP newsgroup(s).