]>
Commit | Line | Data |
---|---|---|
a82817d0 GKH |
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) |