]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.12/r8169-offical-fix-for-cve-2009-4537-overlength-frame-dmas.patch
Fixes for 5.10
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.12 / r8169-offical-fix-for-cve-2009-4537-overlength-frame-dmas.patch
CommitLineData
a82817d0
GKH
1From c0cd884af045338476b8e69a61fceb3f34ff22f1 Mon Sep 17 00:00:00 2001
2From: Neil Horman <nhorman@redhat.com>
3Date: Mon, 29 Mar 2010 13:16:02 -0700
4Subject: r8169: offical fix for CVE-2009-4537 (overlength frame DMAs)
5
6From: Neil Horman <nhorman@redhat.com>
7
8commit c0cd884af045338476b8e69a61fceb3f34ff22f1 upstream.
9
10Official patch to fix the r8169 frame length check error.
11
12Based on this initial thread:
13http://marc.info/?l=linux-netdev&m=126202972828626&w=1
14This is the official patch to fix the frame length problems in the r8169
15driver. As noted in the previous thread, while this patch incurs a performance
16hit on the driver, its possible to improve performance dynamically by updating
17the mtu and rx_copybreak values at runtime to return performance to what it was
18for those NICS which are unaffected by the ideosyncracy (if there are any).
19
20Summary:
21
22 A while back Eric submitted a patch for r8169 in which the proper
23allocated frame size was written to RXMaxSize to prevent the NIC from dmaing too
24much data. This was done in commit fdd7b4c3302c93f6833e338903ea77245eb510b4. A
25long time prior to that however, Francois posted
26126fa4b9ca5d9d7cb7d46f779ad3bd3631ca387c, which expiclitly disabled the MaxSize
27setting due to the fact that the hardware behaved in odd ways when overlong
28frames were received on NIC's supported by this driver. This was mentioned in a
29security conference recently:
30http://events.ccc.de/congress/2009/Fahrplan//events/3596.en.html
31
32It seems that if we can't enable frame size filtering, then, as Eric correctly
33noticed, we can find ourselves DMA-ing too much data to a buffer, causing
34corruption. As a result is seems that we are forced to allocate a frame which
35is ready to handle a maximally sized receive.
36
37This obviously has performance issues with it, so to mitigate that issue, this
38patch does two things:
39
401) Raises the copybreak value to the frame allocation size, which should force
41appropriately sized packets to get allocated on rx, rather than a full new 16k
42buffer.
43
442) This patch only disables frame filtering initially (i.e., during the NIC
45open), changing the MTU results in ring buffer allocation of a size in relation
46to the new mtu (along with a warning indicating that this is dangerous).
47
48Because of item (2), individuals who can't cope with the performance hit (or can
49otherwise filter frames to prevent the bug), or who have hardware they are sure
50is unaffected by this issue, can manually lower the copybreak and reset the mtu
51such that performance is restored easily.
52
53Signed-off-by: Neil Horman <nhorman@redhat.com>
54Signed-off-by: David S. Miller <davem@davemloft.net>
55Cc: maximilian attems <max@stro.at>
56Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
57
58---
59 drivers/net/r8169.c | 29 ++++++++++++++++++++++++-----
60 1 file changed, 24 insertions(+), 5 deletions(-)
61
62--- a/drivers/net/r8169.c
63+++ b/drivers/net/r8169.c
64@@ -186,7 +186,12 @@ static struct pci_device_id rtl8169_pci_
65
66 MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
67
68-static int rx_copybreak = 200;
69+/*
70+ * we set our copybreak very high so that we don't have
71+ * to allocate 16k frames all the time (see note in
72+ * rtl8169_open()
73+ */
74+static int rx_copybreak = 16383;
75 static int use_dac;
76 static struct {
77 u32 msg_enable;
78@@ -3245,9 +3250,13 @@ static void __devexit rtl8169_remove_one
79 }
80
81 static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
82- struct net_device *dev)
83+ unsigned int mtu)
84 {
85- unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
86+ unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
87+
88+ if (max_frame != 16383)
89+ printk(KERN_WARNING "WARNING! Changing of MTU on this NIC"
90+ "May lead to frame reception errors!\n");
91
92 tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
93 }
94@@ -3259,7 +3268,17 @@ static int rtl8169_open(struct net_devic
95 int retval = -ENOMEM;
96
97
98- rtl8169_set_rxbufsize(tp, dev);
99+ /*
100+ * Note that we use a magic value here, its wierd I know
101+ * its done because, some subset of rtl8169 hardware suffers from
102+ * a problem in which frames received that are longer than
103+ * the size set in RxMaxSize register return garbage sizes
104+ * when received. To avoid this we need to turn off filtering,
105+ * which is done by setting a value of 16383 in the RxMaxSize register
106+ * and allocating 16k frames to handle the largest possible rx value
107+ * thats what the magic math below does.
108+ */
109+ rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN);
110
111 /*
112 * Rx and Tx desscriptors needs 256 bytes alignment.
113@@ -3912,7 +3931,7 @@ static int rtl8169_change_mtu(struct net
114
115 rtl8169_down(dev);
116
117- rtl8169_set_rxbufsize(tp, dev);
118+ rtl8169_set_rxbufsize(tp, dev->mtu);
119
120 ret = rtl8169_init_ring(dev);
121 if (ret < 0)