[TG3]: Fix array overrun in tg3_read_partno().
Use proper upper limits for the loops and check for all error conditions. The problem was noticed by Adrian Bunk. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
25f484a62e
commit
af2c6a4aaa
@@ -10212,7 +10212,7 @@ skip_phy_reset:
|
|||||||
static void __devinit tg3_read_partno(struct tg3 *tp)
|
static void __devinit tg3_read_partno(struct tg3 *tp)
|
||||||
{
|
{
|
||||||
unsigned char vpd_data[256];
|
unsigned char vpd_data[256];
|
||||||
int i;
|
unsigned int i;
|
||||||
u32 magic;
|
u32 magic;
|
||||||
|
|
||||||
if (tg3_nvram_read_swab(tp, 0x0, &magic))
|
if (tg3_nvram_read_swab(tp, 0x0, &magic))
|
||||||
@@ -10258,9 +10258,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now parse and find the part number. */
|
/* Now parse and find the part number. */
|
||||||
for (i = 0; i < 256; ) {
|
for (i = 0; i < 254; ) {
|
||||||
unsigned char val = vpd_data[i];
|
unsigned char val = vpd_data[i];
|
||||||
int block_end;
|
unsigned int block_end;
|
||||||
|
|
||||||
if (val == 0x82 || val == 0x91) {
|
if (val == 0x82 || val == 0x91) {
|
||||||
i = (i + 3 +
|
i = (i + 3 +
|
||||||
@@ -10276,21 +10276,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
|
|||||||
(vpd_data[i + 1] +
|
(vpd_data[i + 1] +
|
||||||
(vpd_data[i + 2] << 8)));
|
(vpd_data[i + 2] << 8)));
|
||||||
i += 3;
|
i += 3;
|
||||||
while (i < block_end) {
|
|
||||||
|
if (block_end > 256)
|
||||||
|
goto out_not_found;
|
||||||
|
|
||||||
|
while (i < (block_end - 2)) {
|
||||||
if (vpd_data[i + 0] == 'P' &&
|
if (vpd_data[i + 0] == 'P' &&
|
||||||
vpd_data[i + 1] == 'N') {
|
vpd_data[i + 1] == 'N') {
|
||||||
int partno_len = vpd_data[i + 2];
|
int partno_len = vpd_data[i + 2];
|
||||||
|
|
||||||
if (partno_len > 24)
|
i += 3;
|
||||||
|
if (partno_len > 24 || (partno_len + i) > 256)
|
||||||
goto out_not_found;
|
goto out_not_found;
|
||||||
|
|
||||||
memcpy(tp->board_part_number,
|
memcpy(tp->board_part_number,
|
||||||
&vpd_data[i + 3],
|
&vpd_data[i], partno_len);
|
||||||
partno_len);
|
|
||||||
|
|
||||||
/* Success. */
|
/* Success. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
i += 3 + vpd_data[i + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Part number not found. */
|
/* Part number not found. */
|
||||||
|
Reference in New Issue
Block a user