[commits] r1763 - trunk/batman-adv

postmaster at open-mesh.org postmaster at open-mesh.org
Sun Aug 8 15:02:15 CEST 2010


Author: marek
Date: 2010-08-08 15:01:05 +0200 (Sun, 08 Aug 2010)
New Revision: 1763

Modified:
   trunk/batman-adv/gateway_client.c
Log:
batman-adv: Fix wrong memory access in gw_is_target

gw_is_target tries to access the data in a udp header without checking
if there is enough data available inside the linear skb head.

Signed-off-by: Sven Eckelmann <sven.eckelmann at gmx.de>

Modified: trunk/batman-adv/gateway_client.c
===================================================================
--- trunk/batman-adv/gateway_client.c	2010-08-08 13:01:02 UTC (rev 1762)
+++ trunk/batman-adv/gateway_client.c	2010-08-08 13:01:05 UTC (rev 1763)
@@ -399,6 +399,7 @@
 	struct ethhdr *ethhdr;
 	struct iphdr *iphdr;
 	struct udphdr *udphdr;
+	unsigned int header_len = 0;
 
 	if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT)
 		return false;
@@ -406,22 +407,39 @@
 	if (!curr_gateway)
 		return false;
 
+	/* check for ethernet header */
+	if (!pskb_may_pull(skb, header_len + ETH_HLEN))
+		return false;
 	ethhdr = (struct ethhdr *)skb->data;
+	header_len += ETH_HLEN;
 
-	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
+	/* check for initial vlan header */
+	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
+		if (!pskb_may_pull(skb, header_len + VLAN_HLEN))
+			return false;
 		ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
+		header_len += VLAN_HLEN;
+	}
 
+	/* check for ip header */
 	if (ntohs(ethhdr->h_proto) != ETH_P_IP)
 		return false;
 
-	iphdr = (struct iphdr *)(((unsigned char *)ethhdr) + ETH_HLEN);
+	if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
+		return false;
+	iphdr = (struct iphdr *)(skb->data + header_len);
+	header_len += iphdr->ihl * 4;
 
+	/* check for udp header */
 	if (iphdr->protocol != IPPROTO_UDP)
 		return false;
 
-	udphdr = (struct udphdr *)(((unsigned char *)iphdr) +
-						(iphdr->ihl * 4));
+	if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr)))
+		return false;
+	udphdr = (struct udphdr *)(skb->data + header_len);
+	header_len += sizeof(struct udphdr);
 
+	/* check for bootp port */
 	if (ntohs(udphdr->dest) != 67)
 		return false;
 



More information about the commits mailing list