Skip to content

Commit 5fc9220

Browse files
gfreewinddavem330
authored andcommitted
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>
1 parent f9094b7 commit 5fc9220

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

drivers/net/ipvlan/ipvlan_core.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,15 @@ bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6)
116116
return false;
117117
}
118118

119-
static void *ipvlan_get_L3_hdr(struct sk_buff *skb, int *type)
119+
static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type)
120120
{
121121
void *lyr3h = NULL;
122122

123123
switch (skb->protocol) {
124124
case htons(ETH_P_ARP): {
125125
struct arphdr *arph;
126126

127-
if (unlikely(!pskb_may_pull(skb, sizeof(*arph))))
127+
if (unlikely(!pskb_may_pull(skb, arp_hdr_len(port->dev))))
128128
return NULL;
129129

130130
arph = arp_hdr(skb);
@@ -510,7 +510,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
510510
struct ipvl_addr *addr;
511511
int addr_type;
512512

513-
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
513+
lyr3h = ipvlan_get_L3_hdr(ipvlan->port, skb, &addr_type);
514514
if (!lyr3h)
515515
goto out;
516516

@@ -539,7 +539,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
539539

540540
if (!ipvlan_is_vepa(ipvlan->port) &&
541541
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);
543543
if (lyr3h) {
544544
addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true);
545545
if (addr) {
@@ -606,7 +606,7 @@ static bool ipvlan_external_frame(struct sk_buff *skb, struct ipvl_port *port)
606606
int addr_type;
607607

608608
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);
610610
if (!lyr3h)
611611
return true;
612612

@@ -627,7 +627,7 @@ static rx_handler_result_t ipvlan_handle_mode_l3(struct sk_buff **pskb,
627627
struct sk_buff *skb = *pskb;
628628
rx_handler_result_t ret = RX_HANDLER_PASS;
629629

630-
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
630+
lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
631631
if (!lyr3h)
632632
goto out;
633633

@@ -666,7 +666,7 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
666666
} else {
667667
struct ipvl_addr *addr;
668668

669-
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
669+
lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
670670
if (!lyr3h)
671671
return ret;
672672

@@ -717,7 +717,7 @@ static struct ipvl_addr *ipvlan_skb_to_addr(struct sk_buff *skb,
717717
if (!port || port->mode != IPVLAN_MODE_L3S)
718718
goto out;
719719

720-
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
720+
lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
721721
if (!lyr3h)
722722
goto out;
723723

0 commit comments

Comments
 (0)