]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - 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
1 From c0cd884af045338476b8e69a61fceb3f34ff22f1 Mon Sep 17 00:00:00 2001
2 From: Neil Horman <nhorman@redhat.com>
3 Date: Mon, 29 Mar 2010 13:16:02 -0700
4 Subject: r8169: offical fix for CVE-2009-4537 (overlength frame DMAs)
5
6 From: Neil Horman <nhorman@redhat.com>
7
8 commit c0cd884af045338476b8e69a61fceb3f34ff22f1 upstream.
9
10 Official patch to fix the r8169 frame length check error.
11
12 Based on this initial thread:
13 http://marc.info/?l=linux-netdev&m=126202972828626&w=1
14 This is the official patch to fix the frame length problems in the r8169
15 driver. As noted in the previous thread, while this patch incurs a performance
16 hit on the driver, its possible to improve performance dynamically by updating
17 the mtu and rx_copybreak values at runtime to return performance to what it was
18 for those NICS which are unaffected by the ideosyncracy (if there are any).
19
20 Summary:
21
22 A while back Eric submitted a patch for r8169 in which the proper
23 allocated frame size was written to RXMaxSize to prevent the NIC from dmaing too
24 much data. This was done in commit fdd7b4c3302c93f6833e338903ea77245eb510b4. A
25 long time prior to that however, Francois posted
26 126fa4b9ca5d9d7cb7d46f779ad3bd3631ca387c, which expiclitly disabled the MaxSize
27 setting due to the fact that the hardware behaved in odd ways when overlong
28 frames were received on NIC's supported by this driver. This was mentioned in a
29 security conference recently:
30 http://events.ccc.de/congress/2009/Fahrplan//events/3596.en.html
31
32 It seems that if we can't enable frame size filtering, then, as Eric correctly
33 noticed, we can find ourselves DMA-ing too much data to a buffer, causing
34 corruption. As a result is seems that we are forced to allocate a frame which
35 is ready to handle a maximally sized receive.
36
37 This obviously has performance issues with it, so to mitigate that issue, this
38 patch does two things:
39
40 1) Raises the copybreak value to the frame allocation size, which should force
41 appropriately sized packets to get allocated on rx, rather than a full new 16k
42 buffer.
43
44 2) This patch only disables frame filtering initially (i.e., during the NIC
45 open), changing the MTU results in ring buffer allocation of a size in relation
46 to the new mtu (along with a warning indicating that this is dangerous).
47
48 Because of item (2), individuals who can't cope with the performance hit (or can
49 otherwise filter frames to prevent the bug), or who have hardware they are sure
50 is unaffected by this issue, can manually lower the copybreak and reset the mtu
51 such that performance is restored easily.
52
53 Signed-off-by: Neil Horman <nhorman@redhat.com>
54 Signed-off-by: David S. Miller <davem@davemloft.net>
55 Cc: maximilian attems <max@stro.at>
56 Signed-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)