lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<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

Powered by Openwall GNU/*/Linux Powered by OpenVZ