lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 11 Nov 2016 15:15:41 +0800
From:   Hayes Wang <hayeswang@...ltek.com>
To:     <netdev@...r.kernel.org>
CC:     <nic_swsd@...ltek.com>, <linux-kernel@...r.kernel.org>,
        <linux-usb@...r.kernel.org>, <mlord@...ox.com>,
        Hayes Wang <hayeswang@...ltek.com>
Subject: [PATCH net 2/2] r8152: rx descriptor check

For some platforms, the data in memory is not the same with the one
from the device. That is, the data of memory is unbelievable. The
check is used to find out this situation.

Signed-off-by: Hayes Wang <hayeswang@...ltek.com>
---
 drivers/net/usb/r8152.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0e42a78..e766121 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1756,6 +1756,43 @@ static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
 	return checksum;
 }
 
+static int invalid_rx_desc(struct r8152 *tp, struct rx_desc *rx_desc)
+{
+	u32 opts1 = le32_to_cpu(rx_desc->opts1);
+	u32 opts2 = le32_to_cpu(rx_desc->opts2);
+	unsigned int pkt_len = opts1 & RX_LEN_MASK;
+
+	switch (tp->version) {
+	case RTL_VER_01:
+	case RTL_VER_02:
+		if (pkt_len > RTL8152_RMS)
+			return -EIO;
+		break;
+	default:
+		if (pkt_len > RTL8153_RMS)
+			return -EIO;
+		break;
+	}
+
+	switch (opts2 & (RD_IPV4_CS | RD_IPV6_CS)) {
+	case (RD_IPV4_CS | RD_IPV6_CS):
+		return -EIO;
+	case RD_IPV4_CS:
+	case RD_IPV6_CS:
+		switch (opts2 & (RD_UDP_CS | RD_TCP_CS)) {
+		case (RD_UDP_CS | RD_TCP_CS):
+			return -EIO;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int rx_bottom(struct r8152 *tp, int budget)
 {
 	unsigned long flags;
@@ -1812,6 +1849,18 @@ static int rx_bottom(struct r8152 *tp, int budget)
 			unsigned int pkt_len;
 			struct sk_buff *skb;
 
+			if (unlikely(invalid_rx_desc(tp, rx_desc))) {
+				if (net_ratelimit())
+					netif_err(tp, rx_err, netdev,
+						  "Memory unbelievable\n");
+				if (tp->netdev->features & NETIF_F_RXCSUM) {
+					tp->netdev->features &= ~NETIF_F_RXCSUM;
+					netif_err(tp, rx_err, netdev,
+						  "rx checksum off\n");
+				}
+				break;
+			}
+
 			pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
 			if (pkt_len < ETH_ZLEN)
 				break;
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ