| From c3ad8ccb007c3b4d9daf33a80f13741a7be80653 Mon Sep 17 00:00:00 2001 |
| From: Willem de Bruijn <willemb@google.com> |
| Date: Tue, 7 Feb 2017 15:57:21 -0500 |
| Subject: [PATCH] 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. |
| |
| 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
| index dd2332390c45..b0a6ab30d8e2 100644 |
| --- a/net/packet/af_packet.c |
| +++ b/net/packet/af_packet.c |
| @@ -2813,7 +2813,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) |
| struct virtio_net_hdr vnet_hdr = { 0 }; |
| int offset = 0; |
| struct packet_sock *po = pkt_sk(sk); |
| - int hlen, tlen; |
| + int hlen, tlen, linear; |
| int extra_len = 0; |
| |
| /* |
| @@ -2874,8 +2874,9 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) |
| err = -ENOBUFS; |
| hlen = LL_RESERVED_SPACE(dev); |
| tlen = dev->needed_tailroom; |
| - skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, |
| - __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len), |
| + linear = __virtio16_to_cpu(vio_le(), 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; |
| -- |
| 2.12.0 |
| |