aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/gateway_client.c
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@web.de>2013-08-06 14:21:15 -0400
committerAntonio Quartulli <ordex@autistici.org>2013-08-10 16:55:42 -0400
commit9d2c9488cedb666bc8206fbdcdc1575e0fbc5929 (patch)
treeeef64eda7ea4985117e5a4ccefaa76578bded182 /net/batman-adv/gateway_client.c
parent645359930231d5e78fd3296a38b98c1a658a7ade (diff)
batman-adv: fix potential kernel paging errors for unicast transmissions
There are several functions which might reallocate skb data. Currently some places keep reusing their old ethhdr pointer regardless of whether they became invalid after such a reallocation or not. This potentially leads to kernel paging errors. This patch fixes these by refetching the ethdr pointer after the potential reallocations. Signed-off-by: Linus Lüssing <linus.luessing@web.de> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Diffstat (limited to 'net/batman-adv/gateway_client.c')
-rw-r--r--net/batman-adv/gateway_client.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index f105219f4a4b..7614af31daff 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -508,6 +508,7 @@ out:
508 return 0; 508 return 0;
509} 509}
510 510
511/* this call might reallocate skb data */
511static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) 512static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len)
512{ 513{
513 int ret = false; 514 int ret = false;
@@ -568,6 +569,7 @@ out:
568 return ret; 569 return ret;
569} 570}
570 571
572/* this call might reallocate skb data */
571bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len) 573bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
572{ 574{
573 struct ethhdr *ethhdr; 575 struct ethhdr *ethhdr;
@@ -619,6 +621,12 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
619 621
620 if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr))) 622 if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr)))
621 return false; 623 return false;
624
625 /* skb->data might have been reallocated by pskb_may_pull() */
626 ethhdr = (struct ethhdr *)skb->data;
627 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
628 ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
629
622 udphdr = (struct udphdr *)(skb->data + *header_len); 630 udphdr = (struct udphdr *)(skb->data + *header_len);
623 *header_len += sizeof(*udphdr); 631 *header_len += sizeof(*udphdr);
624 632
@@ -634,12 +642,14 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
634 return true; 642 return true;
635} 643}
636 644
645/* this call might reallocate skb data */
637bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, 646bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
638 struct sk_buff *skb, struct ethhdr *ethhdr) 647 struct sk_buff *skb)
639{ 648{
640 struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL; 649 struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL;
641 struct batadv_orig_node *orig_dst_node = NULL; 650 struct batadv_orig_node *orig_dst_node = NULL;
642 struct batadv_gw_node *curr_gw = NULL; 651 struct batadv_gw_node *curr_gw = NULL;
652 struct ethhdr *ethhdr;
643 bool ret, out_of_range = false; 653 bool ret, out_of_range = false;
644 unsigned int header_len = 0; 654 unsigned int header_len = 0;
645 uint8_t curr_tq_avg; 655 uint8_t curr_tq_avg;
@@ -648,6 +658,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
648 if (!ret) 658 if (!ret)
649 goto out; 659 goto out;
650 660
661 ethhdr = (struct ethhdr *)skb->data;
651 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source, 662 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
652 ethhdr->h_dest); 663 ethhdr->h_dest);
653 if (!orig_dst_node) 664 if (!orig_dst_node)