Sophie

Sophie

distrib > Scientific%20Linux > 5x > i386 > by-pkgid > 351d529f9beeb4e5d936a6d5e3e7813a > files > 1618

kernel-2.6.18-128.29.1.el5.src.rpm

From: Neil Horman <nhorman@redhat.com>
Date: Wed, 20 Jan 2010 13:01:17 -0500
Subject: [net] r8169: improved frame length filtering
Message-id: 20100120180117.GC6313@hmsreliant.think-freely.org
O-Subject: [kernel team] [RHEL 5.3z PATCH] r8169: fix overlength check (bz 550913)
Bugzilla: 550913
CVE: CVE-2009-4537

5.3.z backport of r8169 overlength check fix

fixes bz 550913


diff -up linux-2.6.18.noarch/drivers/net/r8169_compat.h.orig linux-2.6.18.noarch/drivers/net/r8169_compat.h
--- linux-2.6.18.noarch/drivers/net/r8169_compat.h.orig	2010-01-20 12:13:40.000000000 -0500
+++ linux-2.6.18.noarch/drivers/net/r8169_compat.h	2010-01-20 13:00:48.000000000 -0500
@@ -56,5 +56,6 @@ static inline int backport_schedule_dela
 
 #define schedule_delayed_work backport_schedule_delayed_work
 
+#define ETH_FCS_LEN 4
 #endif
 
diff -up linux-2.6.18.noarch/drivers/net/r8169.c.orig linux-2.6.18.noarch/drivers/net/r8169.c
--- linux-2.6.18.noarch/drivers/net/r8169.c.orig	2010-01-20 12:13:51.000000000 -0500
+++ linux-2.6.18.noarch/drivers/net/r8169.c	2010-01-20 13:00:48.000000000 -0500
@@ -182,7 +182,12 @@ static struct pci_device_id rtl8169_pci_
 
 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;
@@ -2183,11 +2188,15 @@ static void __devexit rtl8169_remove_one
 }
 
 static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
-				  struct net_device *dev)
+				  unsigned int mtu)
 {
-	unsigned int mtu = dev->mtu;
+	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 = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
+	tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
 }
 
 static int rtl8169_open(struct net_device *dev)
@@ -2197,7 +2206,17 @@ static int rtl8169_open(struct net_devic
 	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.
@@ -2852,7 +2871,7 @@ static int rtl8169_change_mtu(struct net
 
 	rtl8169_down(dev);
 
-	rtl8169_set_rxbufsize(tp, dev);
+	rtl8169_set_rxbufsize(tp, dev->mtu);
 
 	ret = rtl8169_init_ring(dev);
 	if (ret < 0)