From: Jay Vadayath <jay@artiphishell.com>
To: "Martin K. Petersen" <martin.petersen@oracle.com>,
"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
Jay Vadayath <jay@artiphishell.com>
Subject: [PATCH] scsi: sd: validate device-supplied mode sense lengths in cache_type_store
Date: Fri, 17 Jul 2026 12:10:21 -0700 [thread overview]
Message-ID: <20260717191023.15011-1-jay@artiphishell.com> (raw)
A malicious/emulated USB mass storage device (or any SCSI target) can
return a MODE SENSE(6/10) response whose header_length plus
block_descriptor_length is >= the size of the on-stack 64-byte buffer.
cache_type_store() computed
buffer_data = buffer + data.header_length + data.block_descriptor_length
and then dereferenced buffer_data[0] and buffer_data[2] without ever
checking that this offset still lies within buffer[]. With a reported
block_descriptor_length of 60 and a 4-byte MODE SENSE(6) header the
offset becomes 64 (== sizeof(buffer)), so buffer_data[0]/buffer_data[2]
read and write past the end of the stack buffer. The subsequent length
computation could also underflow and let buffer_data + len run past the
buffer when handed to scsi_mode_select().
KASAN report from an unprivileged user writing to the sysfs cache_type
attribute of a device backed by a raw-gadget mass storage emulator:
BUG: KASAN: stack-out-of-bounds in cache_type_store+0x8ba/0x8f0
Read of size 1 at addr ffff888003097c72 by task poc/57
Call Trace:
dump_stack_lvl+0x53/0x70
print_report+0xce/0x610
kasan_report+0xce/0x100
cache_type_store+0x8ba/0x8f0
kernfs_fop_write_iter+0x384/0x4f0
vfs_write+0x5c7/0xe60
ksys_write+0xf7/0x1c0
do_syscall_64+0x61/0x480
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Reject responses whose mode page offset does not leave room for the
three caching-mode-page bytes we touch, and bound the length by the
space actually remaining in the buffer, mirroring the careful bounds
checking already done in sd_read_cache_type().
This bug was discovered by Artiphishell's vTriage pipeline, which
generated a userspace raw-gadget reproducer that reliably triggers the
KASAN report on an unpatched kernel. The fix below was drafted with the
Claude coding assistant; a userspace reproducer is available on
request.
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Jay Vadayath <jay@artiphishell.com>
---
drivers/scsi/sd.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -228,7 +228,7 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
struct scsi_mode_data data;
struct scsi_sense_hdr sshdr;
static const char temp[] = "temporary ";
- int len, ret;
+ int len, offset, ret;
if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
/* no cache control on RBC devices; theoretically they
@@ -265,13 +265,22 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
return count;
}
if (scsi_mode_sense(sdp, 0x08, 8, 0, buffer, sizeof(buffer), SD_TIMEOUT,
sdkp->max_retries, &data, NULL))
return -EINVAL;
- len = min_t(size_t, sizeof(buffer), data.length - data.header_length -
- data.block_descriptor_length);
- buffer_data = buffer + data.header_length +
- data.block_descriptor_length;
+
+ /*
+ * The mode parameter header and block descriptor lengths are
+ * supplied by the device and must not be trusted (e.g. a malicious
+ * USB mass storage device). Reject responses that would place the
+ * caching mode page (of which we touch the first three bytes)
+ * outside of the buffer to avoid an out-of-bounds access below.
+ */
+ offset = data.header_length + data.block_descriptor_length;
+ if (offset + 3 > sizeof(buffer))
+ return -EINVAL;
+ len = min_t(size_t, sizeof(buffer) - offset, data.length - offset);
+ buffer_data = buffer + offset;
buffer_data[2] &= ~0x05;
buffer_data[2] |= wce << 2 | rcd;
sp = buffer_data[0] & 0x80 ? 1 : 0;
next reply other threads:[~2026-07-17 19:10 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-17 19:10 Jay Vadayath [this message]
2026-07-17 19:24 ` James Bottomley
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=20260717191023.15011-1-jay@artiphishell.com \
--to=jay@artiphishell.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
/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