Patch "ipv6: fix ip6_tnl_parse_tlv_enc_lim()" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
ipv6: fix ip6_tnl_parse_tlv_enc_lim()
to the 4.9-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:
ipv6-fix-ip6_tnl_parse_tlv_enc_lim.patch
and it can be found in the queue-4.9 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 Tue Feb 14 17:03:08 PST 2017
From: Eric Dumazet <[email protected]>
Date: Mon, 23 Jan 2017 16:43:06 -0800
Subject: ipv6: fix ip6_tnl_parse_tlv_enc_lim()
From: Eric Dumazet <[email protected]>
[ Upstream commit fbfa743a9d2a0ffa24251764f10afc13eb21e739 ]
This function suffers from multiple issues.
First one is that pskb_may_pull() may reallocate skb->head, so the 'raw' pointer needs either to be reloaded or not used at all.
Second issue is that NEXTHDR_DEST handling does not validate that the options are present in skb->data, so we might read garbage or access non existent memory.
With help from Willem de Bruijn.
--- net/ipv6/ip6_tunnel.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-)
net/ipv6/ip6_tunnel.c +22 -12
@@ -400,18 +400,19 @@ ip6_tnl_dev_uninit(struct net_device *de__u16 ip6_tnl_parse_tlv_enc_lim (struct sk_buff *skb,__u8 *raw) { -const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) raw; -__u8 nexthdr = ipv6h->nexthdr; -__u16 off =sizeof (*ipv6h); +const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)raw; +unsigned int nhoff = raw - skb->data; +unsigned int off = nhoff +sizeof (*ipv6h); +u8 next, nexthdr = ipv6h->nexthdr;while (ipv6_ext_hdr (nexthdr) && nexthdr !=NEXTHDR_NONE ) { -__u16 optlen =0 ;struct ipv6_opt_hdr *hdr; -if (raw + off +sizeof (*hdr) > skb->data && - !pskb_may_pull (skb, raw - skb->data + off +sizeof (*hdr))) +u16 optlen; + +if (!pskb_may_pull (skb, off +sizeof (*hdr)))break ; - hdr = (struct ipv6_opt_hdr *) (raw + off); + hdr = (struct ipv6_opt_hdr *)(skb->data + off);if (nexthdr ==NEXTHDR_FRAGMENT ) {struct frag_hdr *frag_hdr = (struct frag_hdr *) hdr;if (frag_hdr->frag_off)
@@ -422,20 +423,29 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct s }else { optlen =ipv6_optlen (hdr); } +/* cache hdr->nexthdr, since pskb_may_pull() might +* invalidate hdr +*/ + next = hdr->nexthdr;if (nexthdr ==NEXTHDR_DEST ) { -__u16 i = off +2 ; +u16 i =2 ; + +/* Remember : hdr is no longer valid at this point. */ +if (!pskb_may_pull (skb, off + optlen)) +break ; +while (1 ) {struct ipv6_tlv_tnl_enc_lim *tel;/* No more room for encapsulation limit */ -if (i +sizeof (*tel) > off + optlen) +if (i +sizeof (*tel) > optlen)break ; - tel = (struct ipv6_tlv_tnl_enc_lim *) &raw[i]; + tel = (struct ipv6_tlv_tnl_enc_lim *) skb->data + off + i;/* return index of option if found and valid */ if (tel->type ==IPV6_TLV_TNL_ENCAP_LIMIT && tel->length ==1 ) -return i; +return i + off - nhoff;/* else jump to next option */ if (tel->type) i += tel->length +2 ;
@@ -443,7 +453,7 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct s i++; } } - nexthdr = hdr->nexthdr; + nexthdr = next; off += optlen; }return 0 ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/ipv6-pointer-math-error-in-ip6_tnl_parse_tlv_enc_lim.patch queue-4.9/netlabel-out-of-bound-access-in-cipso_v4_validate.patch queue-4.9/packet-round-up-linear-to-header-len.patch queue-4.9/tun-read-vnet_hdr_sz-once.patch queue-4.9/ipv6-fix-ip6_tnl_parse_tlv_enc_lim.patch queue-4.9/l2tp-do-not-use-udp_ioctl.patch queue-4.9/tcp-fix-0-divide-in-__tcp_select_window.patch queue-4.9/can-fix-kernel-panic-at-security_sock_rcv_skb.patch queue-4.9/net-introduce-device-min_header_len.patch queue-4.9/macvtap-read-vnet_hdr_size-once.patch queue-4.9/tcp-avoid-infinite-loop-in-tcp_splice_read.patch queue-4.9/mlx4-invoke-softirqs-after-napi_reschedule.patch queue-4.9/ipv6-tcp-add-a-missing-tcp_v6_restore_cb.patch queue-4.9/ipv4-keep-skb-dst-around-in-presence-of-ip-options.patch queue-4.9/net-use-a-work-queue-to-defer-net_disable_timestamp-work.patch queue-4.9/ip6_gre-fix-ip6gre_err-invalid-reads.patch