net: s2io: fix buffer overflow
[pandora-kernel.git] / drivers / net / s2io.c
index d0af924..18bc5b7 100644 (file)
@@ -1,6 +1,6 @@
 /************************************************************************
  * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
- * Copyright(c) 2002-2007 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
  *
  * This software may be used and distributed according to the terms of
  * the GNU General Public License (GPL), incorporated herein by reference.
@@ -5796,7 +5796,7 @@ static void s2io_vpd_read(struct s2io_nic *nic)
 {
        u8 *vpd_data;
        u8 data;
-       int i = 0, cnt, fail = 0;
+       int i = 0, cnt, len, fail = 0;
        int vpd_addr = 0x80;
        struct swStat *swstats = &nic->mac_control.stats_info->sw_stat;
 
@@ -5837,20 +5837,28 @@ static void s2io_vpd_read(struct s2io_nic *nic)
 
        if (!fail) {
                /* read serial number of adapter */
-               for (cnt = 0; cnt < 256; cnt++) {
+               for (cnt = 0; cnt < 252; cnt++) {
                        if ((vpd_data[cnt] == 'S') &&
-                           (vpd_data[cnt+1] == 'N') &&
-                           (vpd_data[cnt+2] < VPD_STRING_LEN)) {
-                               memset(nic->serial_num, 0, VPD_STRING_LEN);
-                               memcpy(nic->serial_num, &vpd_data[cnt + 3],
-                                      vpd_data[cnt+2]);
-                               break;
+                           (vpd_data[cnt+1] == 'N')) {
+                               len = vpd_data[cnt+2];
+                               if (len < min(VPD_STRING_LEN, 256-cnt-2)) {
+                                       memcpy(nic->serial_num,
+                                              &vpd_data[cnt + 3],
+                                              len);
+                                       memset(nic->serial_num+len,
+                                              0,
+                                              VPD_STRING_LEN-len);
+                                       break;
+                               }
                        }
                }
        }
 
-       if ((!fail) && (vpd_data[1] < VPD_STRING_LEN))
-               memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
+       if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) {
+               len = vpd_data[1];
+               memcpy(nic->product_name, &vpd_data[3], len);
+               nic->product_name[len] = 0;
+       }
        kfree(vpd_data);
        swstats->mem_freed += 256;
 }
@@ -7886,7 +7894,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
        /*  Private member variable initialized to s2io NIC structure */
        sp = netdev_priv(dev);
-       memset(sp, 0, sizeof(struct s2io_nic));
        sp->dev = dev;
        sp->pdev = pdev;
        sp->high_dma_flag = dma_flag;
@@ -8199,7 +8206,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                goto register_failed;
        }
        s2io_vpd_read(sp);
-       DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2007 Neterion Inc.\n");
+       DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2010 Exar Corp.\n");
        DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n", dev->name,
                  sp->product_name, pdev->revision);
        DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,