From 2765bc9d5159f67b92404c120173cea2091b2adb Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Tue, 30 Mar 2010 06:53:25 +0000 Subject: main/linux-grsec: r8169 fixes --- main/linux-grsec/APKBUILD | 6 +- ...t-78f1cd-r8169-fix-broken-register-writes.patch | 51 +++++++++ ...x-for-CVE-2009-4537-overlength-frame-DMAs.patch | 119 +++++++++++++++++++++ 3 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 main/linux-grsec/net-git-78f1cd-r8169-fix-broken-register-writes.patch create mode 100644 main/linux-grsec/net-git-c0cd88-r8169-offical-fix-for-CVE-2009-4537-overlength-frame-DMAs.patch (limited to 'main/linux-grsec') diff --git a/main/linux-grsec/APKBUILD b/main/linux-grsec/APKBUILD index f54026e0..4d376546 100644 --- a/main/linux-grsec/APKBUILD +++ b/main/linux-grsec/APKBUILD @@ -4,7 +4,7 @@ _flavor=grsec pkgname=linux-${_flavor} pkgver=2.6.32.10 _kernver=2.6.32 -pkgrel=0 +pkgrel=1 pkgdesc="Linux kernel with grsecurity" url=http://grsecurity.net depends="mkinitfs linux-firmware" @@ -19,6 +19,8 @@ source="ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-$_kernver.tar.bz2 ip_gre2.patch arp.patch xfrm-cache-size-revert.patch + net-git-78f1cd-r8169-fix-broken-register-writes.patch + net-git-c0cd88-r8169-offical-fix-for-CVE-2009-4537-overlength-frame-DMAs.patch kernelconfig.x86 " subpackages="$pkgname-dev linux-firmware:firmware" @@ -129,4 +131,6 @@ a1959ececf64be61488ed84d0252c053 grsecurity-2.1.14-2.6.32.10-201003211638.patch 13ca9e91700e459da269c957062bbea7 ip_gre2.patch 4c39a161d918e7f274292ecfd168b891 arp.patch 329fcab881425e001d3243caa4648478 xfrm-cache-size-revert.patch +21ed38773d846097b7315e1e0801d87a net-git-78f1cd-r8169-fix-broken-register-writes.patch +962a6dd7c639612fc8bdaeb836388b0b net-git-c0cd88-r8169-offical-fix-for-CVE-2009-4537-overlength-frame-DMAs.patch 7f442049b29ab749180e54ff8f20f1d0 kernelconfig.x86" diff --git a/main/linux-grsec/net-git-78f1cd-r8169-fix-broken-register-writes.patch b/main/linux-grsec/net-git-78f1cd-r8169-fix-broken-register-writes.patch new file mode 100644 index 00000000..f5f72acc --- /dev/null +++ b/main/linux-grsec/net-git-78f1cd-r8169-fix-broken-register-writes.patch @@ -0,0 +1,51 @@ +From 78f1cd02457252e1ffbc6caa44a17424a45286b8 Mon Sep 17 00:00:00 2001 +From: Francois Romieu +Date: Sat, 27 Mar 2010 19:35:46 -0700 +Subject: [PATCH] r8169: fix broken register writes +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +This is quite similar to b39fe41f481d20c201012e4483e76c203802dda7 +though said registers are not even documented as 64-bit registers +- as opposed to the initial TxDescStartAddress ones - but as single +bytes which must be combined into 32 bits at the MMIO read/write +level before being merged into a 64 bit logical entity. + +Credits go to Ben Hutchings for the MAR +registers (aka "multicast is broken for ages on ARM) and to +Timo Teräs for the MAC registers. + +Signed-off-by: Francois Romieu +Signed-off-by: David S. Miller +--- + drivers/net/r8169.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c +index b93fd23..7193afc 100644 +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -2820,8 +2820,8 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) + spin_lock_irq(&tp->lock); + + RTL_W8(Cfg9346, Cfg9346_Unlock); +- RTL_W32(MAC0, low); + RTL_W32(MAC4, high); ++ RTL_W32(MAC0, low); + RTL_W8(Cfg9346, Cfg9346_Lock); + + spin_unlock_irq(&tp->lock); +@@ -4747,8 +4747,8 @@ static void rtl_set_rx_mode(struct net_device *dev) + mc_filter[1] = swab32(data); + } + +- RTL_W32(MAR0 + 0, mc_filter[0]); + RTL_W32(MAR0 + 4, mc_filter[1]); ++ RTL_W32(MAR0 + 0, mc_filter[0]); + + RTL_W32(RxConfig, tmp); + +-- +1.7.0.3 + diff --git a/main/linux-grsec/net-git-c0cd88-r8169-offical-fix-for-CVE-2009-4537-overlength-frame-DMAs.patch b/main/linux-grsec/net-git-c0cd88-r8169-offical-fix-for-CVE-2009-4537-overlength-frame-DMAs.patch new file mode 100644 index 00000000..250c85d6 --- /dev/null +++ b/main/linux-grsec/net-git-c0cd88-r8169-offical-fix-for-CVE-2009-4537-overlength-frame-DMAs.patch @@ -0,0 +1,119 @@ +From c0cd884af045338476b8e69a61fceb3f34ff22f1 Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Mon, 29 Mar 2010 13:16:02 -0700 +Subject: [PATCH] r8169: offical fix for CVE-2009-4537 (overlength frame DMAs) + +Official patch to fix the r8169 frame length check error. + +Based on this initial thread: +http://marc.info/?l=linux-netdev&m=126202972828626&w=1 +This is the official patch to fix the frame length problems in the r8169 +driver. As noted in the previous thread, while this patch incurs a performance +hit on the driver, its possible to improve performance dynamically by updating +the mtu and rx_copybreak values at runtime to return performance to what it was +for those NICS which are unaffected by the ideosyncracy (if there are any). + +Summary: + + A while back Eric submitted a patch for r8169 in which the proper +allocated frame size was written to RXMaxSize to prevent the NIC from dmaing too +much data. This was done in commit fdd7b4c3302c93f6833e338903ea77245eb510b4. A +long time prior to that however, Francois posted +126fa4b9ca5d9d7cb7d46f779ad3bd3631ca387c, which expiclitly disabled the MaxSize +setting due to the fact that the hardware behaved in odd ways when overlong +frames were received on NIC's supported by this driver. This was mentioned in a +security conference recently: +http://events.ccc.de/congress/2009/Fahrplan//events/3596.en.html + +It seems that if we can't enable frame size filtering, then, as Eric correctly +noticed, we can find ourselves DMA-ing too much data to a buffer, causing +corruption. As a result is seems that we are forced to allocate a frame which +is ready to handle a maximally sized receive. + +This obviously has performance issues with it, so to mitigate that issue, this +patch does two things: + +1) Raises the copybreak value to the frame allocation size, which should force +appropriately sized packets to get allocated on rx, rather than a full new 16k +buffer. + +2) This patch only disables frame filtering initially (i.e., during the NIC +open), changing the MTU results in ring buffer allocation of a size in relation +to the new mtu (along with a warning indicating that this is dangerous). + +Because of item (2), individuals who can't cope with the performance hit (or can +otherwise filter frames to prevent the bug), or who have hardware they are sure +is unaffected by this issue, can manually lower the copybreak and reset the mtu +such that performance is restored easily. + +Signed-off-by: Neil Horman +Signed-off-by: David S. Miller +--- + drivers/net/r8169.c | 29 ++++++++++++++++++++++++----- + 1 files changed, 24 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c +index 7193afc..9674005 100644 +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -186,7 +186,12 @@ static DEFINE_PCI_DEVICE_TABLE(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; +@@ -3217,9 +3222,13 @@ 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; + } +@@ -3231,7 +3240,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. +@@ -3884,7 +3903,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) +-- +1.7.0.3 + -- cgit v1.2.3