From patchwork Sun Aug 1 21:20:13 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 345 Return-Path: Received: from mail.gmx.net (mailout-de.gmx.net [213.165.64.23]) by open-mesh.net (Postfix) with SMTP id 85F25154547 for ; Sun, 1 Aug 2010 23:20:47 +0200 (CEST) Received: (qmail invoked by alias); 01 Aug 2010 21:20:47 -0000 Received: from i59F6B41E.versanet.de (EHLO sven-desktop.lazhur.ath.cx) [89.246.180.30] by mail.gmx.net (mp047) with SMTP; 01 Aug 2010 23:20:47 +0200 X-Authenticated: #15668376 X-Provags-ID: V01U2FsdGVkX18AzBJcGrYAHNC9RHSrPzkxFS0RAo6KY8wUwC5f7t bXVSa34cqhKHwz From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Sun, 1 Aug 2010 23:20:13 +0200 Message-Id: <1280697613-32001-8-git-send-email-sven.eckelmann@gmx.de> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1280697613-32001-1-git-send-email-sven.eckelmann@gmx.de> References: <1280697613-32001-1-git-send-email-sven.eckelmann@gmx.de> X-Y-GMX-Trusted: 0 Subject: [B.A.T.M.A.N.] [PATCH 7/7] batman-adv: Fix wrong memory access in gw_is_target X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.11 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Aug 2010 21:20:47 -0000 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 --- batman-adv/gateway_client.c | 26 ++++++++++++++++++++++---- 1 files changed, 22 insertions(+), 4 deletions(-) diff --git a/batman-adv/gateway_client.c b/batman-adv/gateway_client.c index f50bc41..2ab8b6b 100644 --- a/batman-adv/gateway_client.c +++ b/batman-adv/gateway_client.c @@ -399,6 +399,7 @@ bool gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) 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 @@ bool gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) 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;