mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 22:26:55 +00:00
macvtap: make sure neighbour code can push ethernet header
Brian reported crashes using IPv6 traffic with macvtap/veth combo. I tracked the crashes in neigh_hh_output() -> memcpy(skb->data - HH_DATA_MOD, hh->hh_data, HH_DATA_MOD); Neighbour code assumes headroom to push Ethernet header is at least 16 bytes. It appears macvtap has only 14 bytes available on arches where NET_IP_ALIGN is 0 (like x86) Effect is a corruption of 2 bytes right before skb->head, and possible crashes if accessing non existing memory. This fix should also increase IPv4 performance, as paranoid code in ip_finish_output2() wont have to call skb_realloc_headroom() Reported-by: Brian Rak <brak@vultr.com> Tested-by: Brian Rak <brak@vultr.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
32034e0580
commit
2f1d8b9e8a
1 changed files with 5 additions and 2 deletions
|
@ -654,11 +654,14 @@ static void macvtap_skb_to_vnet_hdr(struct macvtap_queue *q,
|
||||||
} /* else everything is zero */
|
} /* else everything is zero */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Neighbour code has some assumptions on HH_DATA_MOD alignment */
|
||||||
|
#define MACVTAP_RESERVE HH_DATA_OFF(ETH_HLEN)
|
||||||
|
|
||||||
/* Get packet from user space buffer */
|
/* Get packet from user space buffer */
|
||||||
static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
||||||
struct iov_iter *from, int noblock)
|
struct iov_iter *from, int noblock)
|
||||||
{
|
{
|
||||||
int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN);
|
int good_linear = SKB_MAX_HEAD(MACVTAP_RESERVE);
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct macvlan_dev *vlan;
|
struct macvlan_dev *vlan;
|
||||||
unsigned long total_len = iov_iter_count(from);
|
unsigned long total_len = iov_iter_count(from);
|
||||||
|
@ -722,7 +725,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
||||||
linear = macvtap16_to_cpu(q, vnet_hdr.hdr_len);
|
linear = macvtap16_to_cpu(q, vnet_hdr.hdr_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, copylen,
|
skb = macvtap_alloc_skb(&q->sk, MACVTAP_RESERVE, copylen,
|
||||||
linear, noblock, &err);
|
linear, noblock, &err);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
Loading…
Reference in a new issue