[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>

authored by Michael Chan and committed by David S. Miller af2c6a4a 25f484a6

+12 -7
+12 -7
drivers/net/tg3.c
··· 10212 static void __devinit tg3_read_partno(struct tg3 *tp) 10213 { 10214 unsigned char vpd_data[256]; 10215 - int i; 10216 u32 magic; 10217 10218 if (tg3_nvram_read_swab(tp, 0x0, &magic)) ··· 10258 } 10259 10260 /* Now parse and find the part number. */ 10261 - for (i = 0; i < 256; ) { 10262 unsigned char val = vpd_data[i]; 10263 - int block_end; 10264 10265 if (val == 0x82 || val == 0x91) { 10266 i = (i + 3 + ··· 10276 (vpd_data[i + 1] + 10277 (vpd_data[i + 2] << 8))); 10278 i += 3; 10279 - while (i < block_end) { 10280 if (vpd_data[i + 0] == 'P' && 10281 vpd_data[i + 1] == 'N') { 10282 int partno_len = vpd_data[i + 2]; 10283 10284 - if (partno_len > 24) 10285 goto out_not_found; 10286 10287 memcpy(tp->board_part_number, 10288 - &vpd_data[i + 3], 10289 - partno_len); 10290 10291 /* Success. */ 10292 return; 10293 } 10294 } 10295 10296 /* Part number not found. */
··· 10212 static void __devinit tg3_read_partno(struct tg3 *tp) 10213 { 10214 unsigned char vpd_data[256]; 10215 + unsigned int i; 10216 u32 magic; 10217 10218 if (tg3_nvram_read_swab(tp, 0x0, &magic)) ··· 10258 } 10259 10260 /* Now parse and find the part number. */ 10261 + for (i = 0; i < 254; ) { 10262 unsigned char val = vpd_data[i]; 10263 + unsigned int block_end; 10264 10265 if (val == 0x82 || val == 0x91) { 10266 i = (i + 3 + ··· 10276 (vpd_data[i + 1] + 10277 (vpd_data[i + 2] << 8))); 10278 i += 3; 10279 + 10280 + if (block_end > 256) 10281 + goto out_not_found; 10282 + 10283 + while (i < (block_end - 2)) { 10284 if (vpd_data[i + 0] == 'P' && 10285 vpd_data[i + 1] == 'N') { 10286 int partno_len = vpd_data[i + 2]; 10287 10288 + i += 3; 10289 + if (partno_len > 24 || (partno_len + i) > 256) 10290 goto out_not_found; 10291 10292 memcpy(tp->board_part_number, 10293 + &vpd_data[i], partno_len); 10294 10295 /* Success. */ 10296 return; 10297 } 10298 + i += 3 + vpd_data[i + 2]; 10299 } 10300 10301 /* Part number not found. */