Commit 72e72674 authored by Eric Dumazet's avatar Eric Dumazet Committed by Greg Kroah-Hartman

macvtap: make sure neighbour code can push ethernet header

[ Upstream commit 2f1d8b9e ]

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: default avatarBrian Rak <brak@vultr.com>
Tested-by: default avatarBrian Rak <brak@vultr.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c9a44034
...@@ -654,11 +654,14 @@ static void macvtap_skb_to_vnet_hdr(struct macvtap_queue *q, ...@@ -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, ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment