aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGao Feng <gfree.wind@vip.163.com>2017-11-22 22:47:11 -0500
committerDavid S. Miller <davem@davemloft.net>2017-11-23 13:37:02 -0500
commit5fc9220a6719574b37813d4330cc5c1ffe6d5c16 (patch)
tree069ad0802e58b2e5e56f7e76c394bc13b40e81eb
parentf9094b7603c011d27db7ba109e69881c72fa611d (diff)
ipvlan: Fix insufficient skb linear check for arp
In the function ipvlan_get_L3_hdr, current codes use pskb_may_pull to make sure the skb header has enough linear room for arp header. But it would access the arp payload in func ipvlan_addr_lookup. So it still may access the unepxected memory. Now use arp_hdr_len(port->dev) instead of the arp header as the param. Signed-off-by: Gao Feng <gfree.wind@vip.163.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index f2a7e929316e..4476425b1033 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -116,7 +116,7 @@ bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6)
116 return false; 116 return false;
117} 117}
118 118
119static void *ipvlan_get_L3_hdr(struct sk_buff *skb, int *type) 119static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type)
120{ 120{
121 void *lyr3h = NULL; 121 void *lyr3h = NULL;
122 122
@@ -124,7 +124,7 @@ static void *ipvlan_get_L3_hdr(struct sk_buff *skb, int *type)
124 case htons(ETH_P_ARP): { 124 case htons(ETH_P_ARP): {
125 struct arphdr *arph; 125 struct arphdr *arph;
126 126
127 if (unlikely(!pskb_may_pull(skb, sizeof(*arph)))) 127 if (unlikely(!pskb_may_pull(skb, arp_hdr_len(port->dev))))
128 return NULL; 128 return NULL;
129 129
130 arph = arp_hdr(skb); 130 arph = arp_hdr(skb);
@@ -510,7 +510,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
510 struct ipvl_addr *addr; 510 struct ipvl_addr *addr;
511 int addr_type; 511 int addr_type;
512 512
513 lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); 513 lyr3h = ipvlan_get_L3_hdr(ipvlan->port, skb, &addr_type);
514 if (!lyr3h) 514 if (!lyr3h)
515 goto out; 515 goto out;
516 516
@@ -539,7 +539,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
539 539
540 if (!ipvlan_is_vepa(ipvlan->port) && 540 if (!ipvlan_is_vepa(ipvlan->port) &&
541 ether_addr_equal(eth->h_dest, eth->h_source)) { 541 ether_addr_equal(eth->h_dest, eth->h_source)) {
542 lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); 542 lyr3h = ipvlan_get_L3_hdr(ipvlan->port, skb, &addr_type);
543 if (lyr3h) { 543 if (lyr3h) {
544 addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true); 544 addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true);
545 if (addr) { 545 if (addr) {
@@ -606,7 +606,7 @@ static bool ipvlan_external_frame(struct sk_buff *skb, struct ipvl_port *port)
606 int addr_type; 606 int addr_type;
607 607
608 if (ether_addr_equal(eth->h_source, skb->dev->dev_addr)) { 608 if (ether_addr_equal(eth->h_source, skb->dev->dev_addr)) {
609 lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); 609 lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
610 if (!lyr3h) 610 if (!lyr3h)
611 return true; 611 return true;
612 612
@@ -627,7 +627,7 @@ static rx_handler_result_t ipvlan_handle_mode_l3(struct sk_buff **pskb,
627 struct sk_buff *skb = *pskb; 627 struct sk_buff *skb = *pskb;
628 rx_handler_result_t ret = RX_HANDLER_PASS; 628 rx_handler_result_t ret = RX_HANDLER_PASS;
629 629
630 lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); 630 lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
631 if (!lyr3h) 631 if (!lyr3h)
632 goto out; 632 goto out;
633 633
@@ -666,7 +666,7 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
666 } else { 666 } else {
667 struct ipvl_addr *addr; 667 struct ipvl_addr *addr;
668 668
669 lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); 669 lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
670 if (!lyr3h) 670 if (!lyr3h)
671 return ret; 671 return ret;
672 672
@@ -717,7 +717,7 @@ static struct ipvl_addr *ipvlan_skb_to_addr(struct sk_buff *skb,
717 if (!port || port->mode != IPVLAN_MODE_L3S) 717 if (!port || port->mode != IPVLAN_MODE_L3S)
718 goto out; 718 goto out;
719 719
720 lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); 720 lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
721 if (!lyr3h) 721 if (!lyr3h)
722 goto out; 722 goto out;
723 723