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