[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