aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-11-07 17:57:51 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-11-07 18:10:16 -0500
commitaf2c6a4aaa2253f1e29df8fb59a3d92174d30a33 (patch)
tree5eb583eb426b70c342d7a5a0577b44564de70538 /drivers/net/tg3.c
parent25f484a62e41be8020b9a31bf50a792baa58d2d4 (diff)
[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>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8f059b7968bd..06e4f77b0988 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10212,7 +10212,7 @@ skip_phy_reset:
10212static void __devinit tg3_read_partno(struct tg3 *tp) 10212static void __devinit tg3_read_partno(struct tg3 *tp)
10213{ 10213{
10214 unsigned char vpd_data[256]; 10214 unsigned char vpd_data[256];
10215 int i; 10215 unsigned int i;
10216 u32 magic; 10216 u32 magic;
10217 10217
10218 if (tg3_nvram_read_swab(tp, 0x0, &magic)) 10218 if (tg3_nvram_read_swab(tp, 0x0, &magic))
@@ -10258,9 +10258,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
10258 } 10258 }
10259 10259
10260 /* Now parse and find the part number. */ 10260 /* Now parse and find the part number. */
10261 for (i = 0; i < 256; ) { 10261 for (i = 0; i < 254; ) {
10262 unsigned char val = vpd_data[i]; 10262 unsigned char val = vpd_data[i];
10263 int block_end; 10263 unsigned int block_end;
10264 10264
10265 if (val == 0x82 || val == 0x91) { 10265 if (val == 0x82 || val == 0x91) {
10266 i = (i + 3 + 10266 i = (i + 3 +
@@ -10276,21 +10276,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
10276 (vpd_data[i + 1] + 10276 (vpd_data[i + 1] +
10277 (vpd_data[i + 2] << 8))); 10277 (vpd_data[i + 2] << 8)));
10278 i += 3; 10278 i += 3;
10279 while (i < block_end) { 10279
10280 if (block_end > 256)
10281 goto out_not_found;
10282
10283 while (i < (block_end - 2)) {
10280 if (vpd_data[i + 0] == 'P' && 10284 if (vpd_data[i + 0] == 'P' &&
10281 vpd_data[i + 1] == 'N') { 10285 vpd_data[i + 1] == 'N') {
10282 int partno_len = vpd_data[i + 2]; 10286 int partno_len = vpd_data[i + 2];
10283 10287
10284 if (partno_len > 24) 10288 i += 3;
10289 if (partno_len > 24 || (partno_len + i) > 256)
10285 goto out_not_found; 10290 goto out_not_found;
10286 10291
10287 memcpy(tp->board_part_number, 10292 memcpy(tp->board_part_number,
10288 &vpd_data[i + 3], 10293 &vpd_data[i], partno_len);
10289 partno_len);
10290 10294
10291 /* Success. */ 10295 /* Success. */
10292 return; 10296 return;
10293 } 10297 }
10298 i += 3 + vpd_data[i + 2];
10294 } 10299 }
10295 10300
10296 /* Part number not found. */ 10301 /* Part number not found. */