]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[TG3]: Fix array overrun in tg3_read_partno().
authorMichael Chan <mchan@broadcom.com>
Sun, 19 Nov 2006 23:12:55 +0000 (00:12 +0100)
committerAdrian Bunk <bunk@stusta.de>
Sun, 19 Nov 2006 23:12:55 +0000 (00:12 +0100)
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: Adrian Bunk <bunk@stusta.de>
drivers/net/tg3.c

index 7d007221cebb810eac8ef2f9285c2cde5216b442..6d638361d1a58167844a065e353a99bd9f02aac8 100644 (file)
@@ -9344,7 +9344,7 @@ skip_phy_reset:
 static void __devinit tg3_read_partno(struct tg3 *tp)
 {
        unsigned char vpd_data[256];
-       int i;
+       unsigned int i;
 
        if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
                /* Sun decided not to put the necessary bits in the
@@ -9367,9 +9367,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
        }
 
        /* Now parse and find the part number. */
-       for (i = 0; i < 256; ) {
+       for (i = 0; i < 254; ) {
                unsigned char val = vpd_data[i];
-               int block_end;
+               unsigned int block_end;
 
                if (val == 0x82 || val == 0x91) {
                        i = (i + 3 +
@@ -9385,21 +9385,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
                             (vpd_data[i + 1] +
                              (vpd_data[i + 2] << 8)));
                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' &&
                            vpd_data[i + 1] == 'N') {
                                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;
 
                                memcpy(tp->board_part_number,
-                                      &vpd_data[i + 3],
-                                      partno_len);
+                                      &vpd_data[i], partno_len);
 
                                /* Success. */
                                return;
                        }
+                       i += 3 + vpd_data[i + 2];
                }
 
                /* Part number not found. */