summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2010-03-30 06:53:25 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2010-03-31 07:58:46 +0000
commita352cc182f54d4367de4a0edd4ba64eecd6af843 (patch)
tree503b51088ef7fe125b4a22766925e271d9b74328
parent6ace2d1d9b9d16c6deda1187a9379381cbb45129 (diff)
downloadaports-a352cc182f54d4367de4a0edd4ba64eecd6af843.tar.bz2
aports-a352cc182f54d4367de4a0edd4ba64eecd6af843.tar.xz
main/linux-grsec: r8169 fixes
(cherry picked from commit 2765bc9d5159f67b92404c120173cea2091b2adb)
-rw-r--r--main/linux-grsec/APKBUILD6
-rw-r--r--main/linux-grsec/net-git-78f1cd-r8169-fix-broken-register-writes.patch51
-rw-r--r--main/linux-grsec/net-git-c0cd88-r8169-offical-fix-for-CVE-2009-4537-overlength-frame-DMAs.patch119
3 files changed, 175 insertions, 1 deletions
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 <romieu@fr.zoreil.com>
+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 <ben@decadent.org.uk> for the MAR
+registers (aka "multicast is broken for ages on ARM) and to
+Timo Teräs <timo.teras@iki.fi> for the MAC registers.
+
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ 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 <nhorman@redhat.com>
+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 <nhorman@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ 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
+