[PATCH] Fix a memory corruption bug in build_mode_page

Ronnie Sahlberg ronniesahlberg
Tue May 6 08:37:07 CEST 2008


If an application is providing a small allocation size when asking for a large
mode page hte memcpy() in build_mode_page can cause memory to be overwritten
and cause a crash.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
---
 usr/spc.c |   63 ++++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/usr/spc.c b/usr/spc.c
index e3e4d98..35de2e1 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -335,22 +335,28 @@ int spc_test_unit(int host_no, struct scsi_cmd *cmd)
  *
  * Returns number of bytes copied.
  */
-static int build_mode_page(uint8_t *data, struct mode_pg *pg, int update)
+static uint8_t *build_mode_page(uint8_t *data, uint8_t *p, int alloc_len,
+struct mode_pg *pg)
 {
-	uint8_t *p;
-	int len;
+	int i;
+
+	if (alloc_len > (p-data))
+		*p = pg->pcode;
+	p++;
+
+
+	if (alloc_len > (p-data))
+		*p = pg->pcode_size;
+	p++;
+

-	len = pg->pcode_size;
-	if (update) {
-		data[0] = pg->pcode;
-		data[1] = len;
+	for (i = 0; i < pg->pcode_size; i++) {
+		if (alloc_len > (p-data))
+			*p = pg->mode_data[i];
+		p++;
 	}
-	p = &data[2];
-	len += 2;
-	if (update)
-		memcpy(p, pg->mode_data, pg->pcode_size);

-	return len;
+	return p;
 }

 /**
@@ -362,12 +368,13 @@ static int build_mode_page(uint8_t *data, struct
mode_pg *pg, int update)
  */
 int spc_mode_sense(int host_no, struct scsi_cmd *cmd)
 {
-	int len = 0;
 	uint8_t *data = NULL, *scb, mode6, dbd, pcode, subpcode;
+	uint8_t *p;
 	uint16_t alloc_len;
 	unsigned char key = ILLEGAL_REQUEST;
 	uint16_t asc = ASC_INVALID_FIELD_IN_CDB;
 	struct mode_pg *pg;
+	int i;

 	scb = cmd->scb;
 	mode6 = (scb[0] == 0x1a);
@@ -383,10 +390,10 @@ int spc_mode_sense(int host_no, struct scsi_cmd *cmd)

 	if (mode6) {
 		alloc_len = scb[4];
-		len = 4;
+		p = &data[4];
 	} else {
 		alloc_len = (scb[7] << 8) + scb[8];
-		len = 8;
+		p = &data[8];
 	}

 	if (scsi_get_in_length(cmd) < alloc_len)
@@ -394,10 +401,11 @@ int spc_mode_sense(int host_no, struct scsi_cmd *cmd)
 	memset(data, 0, alloc_len);

 	if (!dbd) {
-		if (alloc_len >= len)
-			memcpy(data + len, cmd->dev->mode_block_descriptor,
-			       BLOCK_DESCRIPTOR_LEN);
-		len += BLOCK_DESCRIPTOR_LEN;
+		for (i = 0; i < BLOCK_DESCRIPTOR_LEN; i++) {
+			if (alloc_len > (p-data))
+				*p = cmd->dev->mode_block_descriptor[i];
+			p++;
+		}
 	}

 	if (pcode == 0x3f) {
@@ -405,25 +413,26 @@ int spc_mode_sense(int host_no, struct scsi_cmd *cmd)
 		for (i = 0; i < ARRAY_SIZE(cmd->dev->mode_pgs); i++) {
 			pg = cmd->dev->mode_pgs[i];
 			if (pg)
-				len += build_mode_page(data + len, pg,
-						       alloc_len >= len);
+				p = build_mode_page(data, p, alloc_len, pg);
 		}
 	} else {
 		pg = cmd->dev->mode_pgs[pcode];
 		if (!pg)
 			goto sense;
-		len += build_mode_page(data + len, pg, alloc_len >= len);
+		p = build_mode_page(data, p, alloc_len, pg);
 	}

 	if (mode6) {
-		data[0] = len - 1;
-		data[3] = dbd ? 0 : BLOCK_DESCRIPTOR_LEN;
+		data[0] = (p - data) - 1;
+		if (alloc_len > 3)
+			data[3] = dbd ? 0 : BLOCK_DESCRIPTOR_LEN;
 	} else {
-		*(uint16_t *)(data) = __cpu_to_be16(len - 2);
-		data[7] = dbd ? 0 : BLOCK_DESCRIPTOR_LEN;
+		*(uint16_t *)(data) = __cpu_to_be16((p - data)-2);
+		if (alloc_len > 7)
+			data[7] = dbd ? 0 : BLOCK_DESCRIPTOR_LEN;
 	}

-	scsi_set_in_resid_by_actual(cmd, len);
+	scsi_set_in_resid_by_actual(cmd, p - data);
 	return SAM_STAT_GOOD;
 sense:
 	scsi_set_in_resid_by_actual(cmd, 0);
-- 
1.5.5

------=_Part_11131_11363071.1210056640593
Content-Type: application/x-gzip;
 name=0004-Fix-a-memory-corruption-bug-in-build_mode_page.patch.gz
Content-Transfer-Encoding: base64
X-Attachment-Id: f_ffw4bnfw0
Content-Disposition: attachment;
 filename=0004-Fix-a-memory-corruption-bug-in-build_mode_page.patch.gz

H4sICCD9H0gAAzAwMDQtRml4LWEtbWVtb3J5LWNvcnJ1cHRpb24tYnVnLWluLWJ1aWxkX21vZGVf
cGFnZS5wYXRjaACtVutz2kYQ/4z+iu2XjoQkrAcgjB8NsXHKlMQpOJ1pM54bPQ5xCUgaPZLQ1P97
906ykMEu9qQaY3R3u799/XaPqzReg+1YTi/o+Qt34Q8c1+z3BlbX9xbHjmVR1+laruMYXcOGt3EE
c5qA6YBhDMUfWIZhSlcIM4RZHEWMwtxdrjyahnCaio2sWr8K1y5bdfx4fS5dujkdwk1BNejDW3fD
YQZg9oe2MzQcUE3DMKR54X2ifj6Ej+9HNxe/3sIV+wYurOk6Tjfgx2laJDlDn7wiBMa/2Cog6zig
JHFDKkmTBbgRuEmyYr4rJFkGSRp/YQGLQoTK1u5qBfiJq/OM/U3h65KiVvaZyyziFOVWbop4HBk4
Mixzyt3wk42sPGIZfDTru0VG753NY/AoxF9o+jVleU4jyY2CSsQFP3WzZUeS5iyMaKDHi4XubV6U
T13XJSiy9ChL/I4P/wBA3wb14KM/+UhgwoKtaAb+0o1CGmhg9zHWjKY8U5msKhpYDgR0RcsNXZGk
gC0WoOshy8E92vrjbd8lFgX0G1CbdoPjQadj9wJqUROw4v1ulwfS1JTQxwfar16Bbts9zbJAFd8D
wC0W5YDnJKdZToqI5TLfWca4imINsjwtfJTwM0b8dQBt/KdIAG3+gRnNizTKICrWmFaIF+Btch53
nDAadLjMkaRnOTLEF5Z2qi0XuDkgObQDN3dra+V5CO0k1IRakeA5VSS1gqrVDuDVy6TEEXQlKxpp
HGrXFsb1XdJbW6UTXHE1VDiRVPHK8IW/LkCuweAc5ETnFhV0sdVqJ3AGSaifJz6Cc81EVYXeyzQJ
b6mGOqA7XGlfRBewVZZEEC0O+tG4fejJ/b7J96uoeJvKDNfGCTA43cUGpqocEr37T9e3vouMCjPs
lhso3YfWHZrnMj+LM+v2pApHPQNrJwTuaDUksHIPQLUdB5UTkZdUMPE+pmqFBYQ7PIajdrukf9/S
TE7//kAzbU7//4+bgut1OwmxjGLPP6ufvm+ZJiqB6XpgHjfffZhONWhnvqcJJ/oaBB6OFpEKBC68
mm5NBpdAZp802C92o0yMTD6jUvhMN2hiMp2O34ymZDb+/cN4fvNQOfNRYjS/IJN3f4ymk0tyNRlP
L3FFLi5fc9H9BDWaBriA7yEEBqyf4ytXEXHgnoxrQVaM/ZvpYk1FtQa2ZhpYrWODfzeG1Quzi5Y4
uYQ1zmVotbY8PgNuvCvoWLVXt6RtzVV+iPwFusI7Z09dOO/cwukpDBRQBdygCTfYgRuUcLVfwt2Q
5oRFHDLMlzL3G3uxNqOUCTnuioR0DVMzzR9ICG+ujOZyyWxDaxg6qd36CelVDZOdzhezQzTpfZcK
jqp8WysLHNAvVdN6qPaZBDTzU5bkcaoJPSif19Pri9/I5Xh+MZu8v7meken4nVKnDifDYwIinbtj
61HBxvA6ML3K8XXA9fuBVg3kFq9ho46i/0oO2wtultesa+BN28OambZm9X+kZnshj2az0Z9kPvlr
LO84noSZUgcP3OFwPzoUEgFBlRx+AfLS3Kd+dx42a4zDr5StK7lHjzJTgvaPISFGg3YcURGu3O10
2lOei2SX3guyiusb7YUx/mAUWW3S6EAsT3j/Qt/v9ifNg4uYw+tgbq9hm+9il8EvYMDwaa5vIeQE
EQRtS6RHbmW7JPTzDTTyjY615XrktxW5NHUGhPhJQfKYeNTsy2UglrKNxHlmJM9B38aoW8qjITqN
EJ9luayN3hI9lZWTNqUZC4i3Ia6fF+6Kt5BWl/6gYO0jB69+bsxHb8n8ZnRD3lxfX+K+YOFQXHwH
0AyeSh0ks9Pr9CTpX8t1fahbDgAA
------=_Part_11131_11363071.1210056640593--



More information about the stgt mailing list