[PATCH] forcedeth: fix random memory scribbling bug

Two critical bugs were found in forcedeth 0.47:
- TSO doesn't work.
- pci_map_single() for the rx buffers is called with size==0. This bug
is critical, it causes random memory corruptions on systems with an
iommu.

Below is a minimal fix for both bugs, for 2.6.15.

TSO will be fixed properly in the next version. Tested on x86-64.

Signed-Off-By: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Manfred Spraul and committed by Linus Torvalds 1836098f 8f43d8e1

+8 -7
+8 -7
drivers/net/forcedeth.c
··· 10 * trademarks of NVIDIA Corporation in the United States and other 11 * countries. 12 * 13 - * Copyright (C) 2003,4 Manfred Spraul 14 * Copyright (C) 2004 Andrew de Quincey (wol support) 15 * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane 16 * IRQ rate fixes, bigendian fixes, cleanups, verification) ··· 100 * 0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check 101 * 0.46: 20 Oct 2005: Add irq optimization modes. 102 * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan. 103 * 104 * Known bugs: 105 * We suspect that on some hardware no TX done interrupts are generated. ··· 112 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few 113 * superfluous timer interrupts from the nic. 114 */ 115 - #define FORCEDETH_VERSION "0.47" 116 #define DRV_NAME "forcedeth" 117 118 #include <linux/module.h> ··· 872 } else { 873 skb = np->rx_skbuff[nr]; 874 } 875 - np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, 876 - PCI_DMA_FROMDEVICE); 877 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { 878 np->rx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); 879 wmb(); ··· 1000 wmb(); 1001 if (np->rx_skbuff[i]) { 1002 pci_unmap_single(np->pci_dev, np->rx_dma[i], 1003 - np->rx_skbuff[i]->len, 1004 PCI_DMA_FROMDEVICE); 1005 dev_kfree_skb(np->rx_skbuff[i]); 1006 np->rx_skbuff[i] = NULL; ··· 1335 * the performance. 1336 */ 1337 pci_unmap_single(np->pci_dev, np->rx_dma[i], 1338 - np->rx_skbuff[i]->len, 1339 PCI_DMA_FROMDEVICE); 1340 1341 { ··· 2456 np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; 2457 dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; 2458 #ifdef NETIF_F_TSO 2459 - dev->features |= NETIF_F_TSO; 2460 #endif 2461 } 2462
··· 10 * trademarks of NVIDIA Corporation in the United States and other 11 * countries. 12 * 13 + * Copyright (C) 2003,4,5 Manfred Spraul 14 * Copyright (C) 2004 Andrew de Quincey (wol support) 15 * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane 16 * IRQ rate fixes, bigendian fixes, cleanups, verification) ··· 100 * 0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check 101 * 0.46: 20 Oct 2005: Add irq optimization modes. 102 * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan. 103 + * 0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single 104 * 105 * Known bugs: 106 * We suspect that on some hardware no TX done interrupts are generated. ··· 111 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few 112 * superfluous timer interrupts from the nic. 113 */ 114 + #define FORCEDETH_VERSION "0.48" 115 #define DRV_NAME "forcedeth" 116 117 #include <linux/module.h> ··· 871 } else { 872 skb = np->rx_skbuff[nr]; 873 } 874 + np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, 875 + skb->end-skb->data, PCI_DMA_FROMDEVICE); 876 if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { 877 np->rx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); 878 wmb(); ··· 999 wmb(); 1000 if (np->rx_skbuff[i]) { 1001 pci_unmap_single(np->pci_dev, np->rx_dma[i], 1002 + np->rx_skbuff[i]->end-np->rx_skbuff[i]->data, 1003 PCI_DMA_FROMDEVICE); 1004 dev_kfree_skb(np->rx_skbuff[i]); 1005 np->rx_skbuff[i] = NULL; ··· 1334 * the performance. 1335 */ 1336 pci_unmap_single(np->pci_dev, np->rx_dma[i], 1337 + np->rx_skbuff[i]->end-np->rx_skbuff[i]->data, 1338 PCI_DMA_FROMDEVICE); 1339 1340 { ··· 2455 np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; 2456 dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; 2457 #ifdef NETIF_F_TSO 2458 + /* disabled dev->features |= NETIF_F_TSO; */ 2459 #endif 2460 } 2461