Patch "packet: validate variable length ll headers" has been added to the 4.5-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
packet: validate variable length ll headers
to the 4.5-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
packet-validate-variable-length-ll-headers.patch
and it can be found in the queue-4.5 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Sat Apr 16 09:15:18 PDT 2016
From: Willem de Bruijn <[email protected]>
Date: Wed, 9 Mar 2016 21:58:34 -0500
Subject: packet: validate variable length ll headers
From: Willem de Bruijn <[email protected]>
[ Upstream commit 9ed988cd591500c040b2a6257bc68543e08ceeef ]
Replace link layer header validation check ll_header_truncate with more generic dev_validate_header.
Validation based on hard_header_len incorrectly drops valid packets in variable length protocols, such as AX25. dev_validate_header calls header_ops.validate for such protocols to ensure correctness below hard_header_len.
See also http://comments.gmane.org/gmane.linux.network/401064
Fixes 9c7077622dd9 ("packet: make packet_snd fail on len smaller than l2 header")
--- net/packet/af_packet.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-)
net/packet/af_packet.c +16 -21
@@ -1916,6 +1916,10 @@ retry: goto retry; } +if (!dev_validate_header (dev, skb->data, len)) { + err = -EINVAL ; + goto out_unlock; + }if (len > (dev->mtu + dev->hard_header_len + extra_len) && !packet_extra_vlan_len_allowed (dev, skb)) { err = -EMSGSIZE ;
@@ -2326,18 +2330,6 @@ static void tpacket_destruct_skb(structsock_wfree (skb); } -static bool ll_header_truncated (const struct net_device *dev,int len) -{ -/* net device doesn't like empty head */ -if (unlikely (len < dev->hard_header_len)) { -net_warn_ratelimited ("%s: packet size is too short (%d < %d)\n" , - current->comm, len, dev->hard_header_len); -return true; - } - -return false; -} -static void tpacket_set_protocol (const struct net_device *dev,struct sk_buff *skb) {
@@ -2420,19 +2412,19 @@ static int tpacket_fill_skb(struct packeif (unlikely (err <0 ))return -EINVAL ; }else if (dev->hard_header_len) { -if (ll_header_truncated (dev, tp_len)) -return -EINVAL ; +int hdrlen =min_t (int, dev->hard_header_len, tp_len);skb_push (skb, dev->hard_header_len); - err =skb_store_bits (skb,0 , data, - dev->hard_header_len); + err =skb_store_bits (skb,0 , data, hdrlen);if (unlikely (err))return err; +if (!dev_validate_header (dev, skb->data, hdrlen)) +return -EINVAL ;if (!skb->protocol)tpacket_set_protocol (dev, skb); - data += dev->hard_header_len; - to_write -= dev->hard_header_len; + data += hdrlen; + to_write -= hdrlen; } offset =offset_in_page (data);
@@ -2763,9 +2755,6 @@ static int packet_snd(struct socket *soc offset =dev_hard_header (skb, dev,ntohs (proto), addr,NULL , len);if (unlikely (offset <0 )) goto out_free; - }else { -if (ll_header_truncated (dev, len)) - goto out_free; }/* Returns -EFAULT on error */
@@ -2773,6 +2762,12 @@ static int packet_snd(struct socket *socif (err) goto out_free; +if (sock->type ==SOCK_RAW && + !dev_validate_header (dev, skb->data, len)) { + err = -EINVAL ; + goto out_free; + } +sock_tx_timestamp (sk, &skb_shinfo (skb)->tx_flags); if (!gso_type && (len > dev->mtu + reserve + extra_len) &&
Patches currently in stable-queue which might be from [email protected] are
queue-4.5/ax25-add-link-layer-header-validation-function.patch queue-4.5/net-validate-variable-length-ll-headers.patch queue-4.5/packet-validate-variable-length-ll-headers.patch queue-4.5/macvtap-always-pass-ethernet-header-in-linear.patch queue-4.5/ipv6-udp-fix-udp_mib_ignoredmulti-updates.patch