aboutsummaryrefslogtreecommitdiff
path: root/net/packet
diff options
context:
space:
mode:
authorWillem de Bruijn <willemb@google.com>2017-02-07 15:57:21 -0500
committerMister Oyster <oysterized@gmail.com>2017-07-04 11:51:33 +0200
commit0458cb3e231dcab869c765a9509660383b83ff33 (patch)
tree81d522b6ccbf53a2a3007752e7bd617454147055 /net/packet
parent81bdc97a16cb396cc748108a5042709b00713e75 (diff)
packet: round up linear to header len
commit 57031eb794906eea4e1c7b31dc1e2429c0af0c66 upstream. Link layer protocols may unconditionally pull headers, as Ethernet does in eth_type_trans. Ensure that the entire link layer header always lies in the skb linear segment. tpacket_snd has such a check. Extend this to packet_snd. Variable length link layer headers complicate the computation somewhat. Here skb->len may be smaller than dev->hard_header_len. Round up the linear length to be at least as long as the smallest of the two. [js] no virtio helpers in 3.12 Reported-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Willem de Bruijn <willemb@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Willy Tarreau <w@1wt.eu>
Diffstat (limited to 'net/packet')
-rw-r--r--net/packet/af_packet.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 9cf3e2110..4dfa37b82 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2243,7 +2243,7 @@ static int packet_snd(struct socket *sock,
int vnet_hdr_len;
struct packet_sock *po = pkt_sk(sk);
unsigned short gso_type = 0;
- int hlen, tlen;
+ int hlen, tlen, linear;
int extra_len = 0;
/*
@@ -2337,7 +2337,9 @@ static int packet_snd(struct socket *sock,
err = -ENOBUFS;
hlen = LL_RESERVED_SPACE(dev);
tlen = dev->needed_tailroom;
- skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len,
+ linear = vnet_hdr.hdr_len;
+ linear = max(linear, min_t(int, len, dev->hard_header_len));
+ skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, linear,
msg->msg_flags & MSG_DONTWAIT, &err);
if (skb == NULL)
goto out_unlock;