From eeba5295fa3482b28baad4e2ac6e5bd321a3b288 Mon Sep 17 00:00:00 2001 From: Maximilian Attems Date: Fri, 19 Feb 2010 18:07:27 +0000 Subject: [PATCH] r8169 patch for rx length check errors. (CVE-2009-4537) patch seen on fedora: "r8169 issue reported at 26c3 (fix taken from Red Hat/CentOS 5.4)" not yet seen upstream. svn path=/dists/sid/linux-2.6/; revision=15230 --- debian/changelog | 1 + ...8169-improved-rx-length-check-errors.patch | 113 ++++++++++++++++++ debian/patches/series/9 | 1 + 3 files changed, 115 insertions(+) create mode 100644 debian/patches/bugfix/all/net-r8169-improved-rx-length-check-errors.patch diff --git a/debian/changelog b/debian/changelog index 3d6dacfa6..65cc88977 100644 --- a/debian/changelog +++ b/debian/changelog @@ -23,6 +23,7 @@ linux-2.6 (2.6.32-9) UNRELEASED; urgency=low - futex_lock_pi() key refcnt fix. (CVE-2010-0623) - Staging: fix rtl8187se compilation errors with mac80211. (closes: #566726) + * r8169 patch for rx length check errors. (CVE-2009-4537) [ Bastian Blank ] * Restrict access to sensitive SysRq keys by default. diff --git a/debian/patches/bugfix/all/net-r8169-improved-rx-length-check-errors.patch b/debian/patches/bugfix/all/net-r8169-improved-rx-length-check-errors.patch new file mode 100644 index 000000000..369c7c687 --- /dev/null +++ b/debian/patches/bugfix/all/net-r8169-improved-rx-length-check-errors.patch @@ -0,0 +1,113 @@ +From: Neil Horman +Date: Tue, 5 Jan 2010 09:43:37 -0500 +Subject: [net] r8169: imporved rx length check errors +Message-id: 20100105144337.GB24293@hmsreliant.think-freely.org +O-Subject: [kernel team] [RHEL 5.5 PATCH] imporved r8169 patch for rx length check errors (bz 522438) +Bugzilla: 552438 +RH-Acked-by: No One + +[ cebbert : ported to 2.6.32 ] + +Hey- + So we've been going back and forth about these r8169 changes( bz 550915). +We have a hardware ideosyncracy that seems to dictate that we disable frame +filtering, and as a result we are forced to allocate very large buffers, which +Dave correctly points out are a major performance impact. This is further +compllicated by the fact that we don't know which subset of hardware is affected +by this bug. As such I've come up with this fix that I _think_ makes everyone +as happy as possible given what we know (or more specifically, what we don't +know). Anywho, I've posted this upstream and am waiting for comments. +Basically, it does the following things + +1) Modifies the setrxbuf routine to accept an mtu paramter + +2) Changes the drivers open routine to force the mtu pased to the function in +(1) a size of 16383-VLAN_ETH_HLEN-ETH_FCS_LEN + +3) raises the copybreak value so that we always allocate frames on rx to pass to +the network stack. + +4) Adds a warning about changing the mtu to a size that is not 16383 + +The effective result of these changes are that by default, we allocate at device +open a ring of 16k buffers which disables filtering, and set the copybreak value +to that size, so that instead of constantly allocating 16k buffers, we just +allocate frame size appropriate buffers. This is still a big performance hit, +but better than constant 16k allocations, which would quickly fail. + +We also (and this is the improved part), allow for user space to set mtu's +smaller than 16383, which results in the driver reverting back to the +pre-patched behavior. A loud warning is issued to this effect, so that people +will realize what their doing, but if a user is in a situation where the can +guarantee frame sizes with other equipment (switch filtering, etc), then this +allows them the old performance levels + +Satisfies bz 522438 + +Neil + +diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c +index 063d949..c241338 100644 +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -181,7 +181,12 @@ static struct pci_device_id rtl8169_pci_tbl[] = { + + MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); + +-static int rx_copybreak = 200; ++/* ++ * we set our copybreak very high so that we don't have ++ * to allocate 16k frames all the time (see note in ++ * rtl8169_open() ++ */ ++static int rx_copybreak = 16383; + static int use_dac; + static struct { + u32 msg_enable; +@@ -2209,11 +2214,15 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) + } + + static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, +- struct net_device *dev) ++ unsigned int mtu) + { +- unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ++ unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ++ ++ if (max_frame != 16383) ++ printk(KERN_WARNING "WARNING! Changing of MTU on this NIC " ++ "May lead to frame reception errors!\n"); + +- tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; ++ tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; + } + + static int rtl8169_open(struct net_device *dev) +@@ -2223,7 +2232,17 @@ static int rtl8169_open(struct net_device *dev) + int retval = -ENOMEM; + + +- rtl8169_set_rxbufsize(tp, dev); ++ /* ++ * Note that we use a magic value here, its wierd I know ++ * its done because, some subset of rtl8169 hardware suffers from ++ * a problem in which frames received that are longer than ++ * the size set in RxMaxSize register return garbage sizes ++ * when received. To avoid this we need to turn off filtering, ++ * which is done by setting a value of 16383 in the RxMaxSize register ++ * and allocating 16k frames to handle the largest possible rx value ++ * thats what the magic math below does. ++ */ ++ rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN); + + /* + * Rx and Tx desscriptors needs 256 bytes alignment. +@@ -2874,7 +2893,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) + + rtl8169_down(dev); + +- rtl8169_set_rxbufsize(tp, dev); ++ rtl8169_set_rxbufsize(tp, dev->mtu); + + ret = rtl8169_init_ring(dev); + if (ret < 0) diff --git a/debian/patches/series/9 b/debian/patches/series/9 index 8a8a4fac8..b0df46a70 100644 --- a/debian/patches/series/9 +++ b/debian/patches/series/9 @@ -12,3 +12,4 @@ - bugfix/all/fix-potential-crash-with-sys_move_pages.patch - bugfix/x86/kvm-pit-control-word-is-write-only.patch + bugfix/all/stable/2.6.32.9-rc1.patch ++ bugfix/all/net-r8169-improved-rx-length-check-errors.patch