aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2015-11-11 17:25:44 -0500
committerDavid S. Miller <davem@davemloft.net>2015-11-15 18:00:35 -0500
commit5cfb4c8d05b4409c4044cb9c05b19705c1d9818b (patch)
treedb5aba8f1e47af35a7557bff779b80a1a0daadbc
parentc72219b75fde768efccf7666342282fab7f9e4e7 (diff)
packet: fix tpacket_snd max frame len
Since it's introduction in commit 69e3c75f4d54 ("net: TX_RING and packet mmap"), TX_RING could be used from SOCK_DGRAM and SOCK_RAW side. When used with SOCK_DGRAM only, the size_max > dev->mtu + reserve check should have reserve as 0, but currently, this is unconditionally set (in it's original form as dev->hard_header_len). I think this is not correct since tpacket_fill_skb() would then take dev->mtu and dev->hard_header_len into account for SOCK_DGRAM, the extra VLAN_HLEN could be possible in both cases. Presumably, the reserve code was copied from packet_snd(), but later on missed the check. Make it similar as we have it in packet_snd(). Fixes: 69e3c75f4d54 ("net: TX_RING and packet mmap") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/packet/af_packet.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 0066da2b8e44..242bce1cf0f3 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2510,12 +2510,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2510 if (unlikely(!(dev->flags & IFF_UP))) 2510 if (unlikely(!(dev->flags & IFF_UP)))
2511 goto out_put; 2511 goto out_put;
2512 2512
2513 reserve = dev->hard_header_len + VLAN_HLEN; 2513 if (po->sk.sk_socket->type == SOCK_RAW)
2514 reserve = dev->hard_header_len;
2514 size_max = po->tx_ring.frame_size 2515 size_max = po->tx_ring.frame_size
2515 - (po->tp_hdrlen - sizeof(struct sockaddr_ll)); 2516 - (po->tp_hdrlen - sizeof(struct sockaddr_ll));
2516 2517
2517 if (size_max > dev->mtu + reserve) 2518 if (size_max > dev->mtu + reserve + VLAN_HLEN)
2518 size_max = dev->mtu + reserve; 2519 size_max = dev->mtu + reserve + VLAN_HLEN;
2519 2520
2520 do { 2521 do {
2521 ph = packet_current_frame(po, &po->tx_ring, 2522 ph = packet_current_frame(po, &po->tx_ring,
@@ -2542,7 +2543,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2542 tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, 2543 tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto,
2543 addr, hlen); 2544 addr, hlen);
2544 if (likely(tp_len >= 0) && 2545 if (likely(tp_len >= 0) &&
2545 tp_len > dev->mtu + dev->hard_header_len && 2546 tp_len > dev->mtu + reserve &&
2546 !packet_extra_vlan_len_allowed(dev, skb)) 2547 !packet_extra_vlan_len_allowed(dev, skb))
2547 tp_len = -EMSGSIZE; 2548 tp_len = -EMSGSIZE;
2548 2549