[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250430115926.6335-1-rand.sec96@gmail.com>
Date: Wed, 30 Apr 2025 14:59:26 +0300
From: Rand Deeb <rand.sec96@...il.com>
To: Finn Thain <fthain@...ux-m68k.org>,
Michael Schmitz <schmitzmic@...il.com>,
"James E.J. Bottomley" <James.Bottomley@...senPartnership.com>,
"Martin K. Petersen" <martin.petersen@...cle.com>,
linux-scsi@...r.kernel.org (open list:NCR 5380 SCSI DRIVERS),
linux-kernel@...r.kernel.org (open list)
Cc: deeb.rand@...fident.ru,
lvc-project@...uxtesting.org,
voskresenski.stanislav@...fident.ru,
Rand Deeb <rand.sec96@...il.com>
Subject: [PATCH] scsi: NCR5380: Prevent potential out-of-bounds read in spi_print_msg()
spi_print_msg() assumes that the input buffer is large enough to
contain the full SCSI message, including extended messages which may
access msg[2], msg[3], msg[7], and beyond based on message type.
NCR5380_reselect() currently allocates a 3-byte buffer for 'msg'
and reads only a single byte from the SCSI bus before passing it to
spi_print_msg(), which can result in a potential out-of-bounds read
if the message is malformed or declares a longer length.
This patch increases the buffer size to 16 bytes and reads up to
16 bytes from the SCSI bus. A length check is also added to ensure
the message is well-formed before passing it to spi_print_msg().
This ensures safe handling of all valid SCSI messages and prevents
undefined behavior due to malformed or malicious input.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Rand Deeb <rand.sec96@...il.com>
---
drivers/scsi/NCR5380.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 0e10502660de..2d2a1244af62 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -2026,7 +2026,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char target_mask;
unsigned char lun;
- unsigned char msg[3];
+ unsigned char msg[16];
struct NCR5380_cmd *ncmd;
struct scsi_cmnd *tmp;
@@ -2084,7 +2084,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
msg[0] = NCR5380_read(CURRENT_SCSI_DATA_REG);
#else
{
- int len = 1;
+ int len = sizeof(msg);
unsigned char *data = msg;
unsigned char phase = PHASE_MSGIN;
@@ -2099,7 +2099,26 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
if (!(msg[0] & 0x80)) {
shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
- spi_print_msg(msg);
+
+ /*
+ * Defensive check before calling spi_print_msg():
+ * Avoid buffer overrun if msg claims extended length.
+ */
+ if (msg[0] == EXTENDED_MESSAGE && len >= 3) {
+ int expected_len = 2 + msg[1];
+
+ if (expected_len == 2)
+ expected_len += 256;
+
+ if (len >= expected_len)
+ spi_print_msg(msg);
+ else
+ pr_warn("spi_print_msg: skipping malformed extended message (len=%d, expected=%d)\n",
+ len, expected_len);
+ } else {
+ spi_print_msg(msg);
+ }
+
printk("\n");
do_abort(instance, 0);
return;
--
2.34.1
Powered by blists - more mailing lists