aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
authorWillem de Bruijn <willemb@google.com>2017-02-07 15:57:21 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-18 09:11:43 -0500
commit82849541895fc355de23aad2ab1615969e50896f (patch)
tree5b96cde258a85d45913cef3b7128764f32ac6a4c /net/packet
parent6ebde312a8ed469172fc9694ca0c8411994d47ff (diff)
packet: round up linear to header len
[ Upstream commit 57031eb794906eea4e1c7b31dc1e2429c0af0c66 ] 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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/packet')
-rw-r--r--net/packet/af_packet.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 94e4a5941d89..458722b938c7 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)
2813 struct virtio_net_hdr vnet_hdr = { 0 }; 2813 struct virtio_net_hdr vnet_hdr = { 0 };
2814 int offset = 0; 2814 int offset = 0;
2815 struct packet_sock *po = pkt_sk(sk); 2815 struct packet_sock *po = pkt_sk(sk);
2816 int hlen, tlen; 2816 int hlen, tlen, linear;
2817 int extra_len = 0; 2817 int extra_len = 0;
2818 2818
2819 /* 2819 /*
@@ -2874,8 +2874,9 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
2874 err = -ENOBUFS; 2874 err = -ENOBUFS;
2875 hlen = LL_RESERVED_SPACE(dev); 2875 hlen = LL_RESERVED_SPACE(dev);
2876 tlen = dev->needed_tailroom; 2876 tlen = dev->needed_tailroom;
2877 skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, 2877 linear = __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len);
2878 __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len), 2878 linear = max(linear, min_t(int, len, dev->hard_header_len));
2879 skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, linear,
2879 msg->msg_flags & MSG_DONTWAIT, &err); 2880 msg->msg_flags & MSG_DONTWAIT, &err);
2880 if (skb == NULL) 2881 if (skb == NULL)
2881 goto out_unlock; 2882 goto out_unlock;