mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08:00
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>
This commit is contained in:
parent
f9094b7603
commit
5fc9220a67
@ -116,7 +116,7 @@ bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void *ipvlan_get_L3_hdr(struct sk_buff *skb, int *type)
|
||||
static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type)
|
||||
{
|
||||
void *lyr3h = NULL;
|
||||
|
||||
@ -124,7 +124,7 @@ static void *ipvlan_get_L3_hdr(struct sk_buff *skb, int *type)
|
||||
case htons(ETH_P_ARP): {
|
||||
struct arphdr *arph;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, sizeof(*arph))))
|
||||
if (unlikely(!pskb_may_pull(skb, arp_hdr_len(port->dev))))
|
||||
return NULL;
|
||||
|
||||
arph = arp_hdr(skb);
|
||||
@ -510,7 +510,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
|
||||
struct ipvl_addr *addr;
|
||||
int addr_type;
|
||||
|
||||
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
|
||||
lyr3h = ipvlan_get_L3_hdr(ipvlan->port, skb, &addr_type);
|
||||
if (!lyr3h)
|
||||
goto out;
|
||||
|
||||
@ -539,7 +539,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
|
||||
|
||||
if (!ipvlan_is_vepa(ipvlan->port) &&
|
||||
ether_addr_equal(eth->h_dest, eth->h_source)) {
|
||||
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
|
||||
lyr3h = ipvlan_get_L3_hdr(ipvlan->port, skb, &addr_type);
|
||||
if (lyr3h) {
|
||||
addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true);
|
||||
if (addr) {
|
||||
@ -606,7 +606,7 @@ static bool ipvlan_external_frame(struct sk_buff *skb, struct ipvl_port *port)
|
||||
int addr_type;
|
||||
|
||||
if (ether_addr_equal(eth->h_source, skb->dev->dev_addr)) {
|
||||
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
|
||||
lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
|
||||
if (!lyr3h)
|
||||
return true;
|
||||
|
||||
@ -627,7 +627,7 @@ static rx_handler_result_t ipvlan_handle_mode_l3(struct sk_buff **pskb,
|
||||
struct sk_buff *skb = *pskb;
|
||||
rx_handler_result_t ret = RX_HANDLER_PASS;
|
||||
|
||||
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
|
||||
lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
|
||||
if (!lyr3h)
|
||||
goto out;
|
||||
|
||||
@ -666,7 +666,7 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
|
||||
} else {
|
||||
struct ipvl_addr *addr;
|
||||
|
||||
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
|
||||
lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
|
||||
if (!lyr3h)
|
||||
return ret;
|
||||
|
||||
@ -717,7 +717,7 @@ static struct ipvl_addr *ipvlan_skb_to_addr(struct sk_buff *skb,
|
||||
if (!port || port->mode != IPVLAN_MODE_L3S)
|
||||
goto out;
|
||||
|
||||
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
|
||||
lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
|
||||
if (!lyr3h)
|
||||
goto out;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user