Patch "ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim()" has been added to the 4.19-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim()

to the 4.19-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:
     ip6_tunnel-fix-nexthdr_fragment-handling-in-ip6_tnl_.patch
and it can be found in the queue-4.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit e1c083ad61c78a79e7d4332e83f24dbc4a3bc387
Author: Eric Dumazet <edumazet@xxxxxxxxxx>
Date:   Fri Jan 5 17:03:13 2024 +0000

    ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim()
    
    [ Upstream commit d375b98e0248980681e5e56b712026174d617198 ]
    
    syzbot pointed out [1] that NEXTHDR_FRAGMENT handling is broken.
    
    Reading frag_off can only be done if we pulled enough bytes
    to skb->head. Currently we might access garbage.
    
    [1]
    BUG: KMSAN: uninit-value in ip6_tnl_parse_tlv_enc_lim+0x94f/0xbb0
    ip6_tnl_parse_tlv_enc_lim+0x94f/0xbb0
    ipxip6_tnl_xmit net/ipv6/ip6_tunnel.c:1326 [inline]
    ip6_tnl_start_xmit+0xab2/0x1a70 net/ipv6/ip6_tunnel.c:1432
    __netdev_start_xmit include/linux/netdevice.h:4940 [inline]
    netdev_start_xmit include/linux/netdevice.h:4954 [inline]
    xmit_one net/core/dev.c:3548 [inline]
    dev_hard_start_xmit+0x247/0xa10 net/core/dev.c:3564
    __dev_queue_xmit+0x33b8/0x5130 net/core/dev.c:4349
    dev_queue_xmit include/linux/netdevice.h:3134 [inline]
    neigh_connected_output+0x569/0x660 net/core/neighbour.c:1592
    neigh_output include/net/neighbour.h:542 [inline]
    ip6_finish_output2+0x23a9/0x2b30 net/ipv6/ip6_output.c:137
    ip6_finish_output+0x855/0x12b0 net/ipv6/ip6_output.c:222
    NF_HOOK_COND include/linux/netfilter.h:303 [inline]
    ip6_output+0x323/0x610 net/ipv6/ip6_output.c:243
    dst_output include/net/dst.h:451 [inline]
    ip6_local_out+0xe9/0x140 net/ipv6/output_core.c:155
    ip6_send_skb net/ipv6/ip6_output.c:1952 [inline]
    ip6_push_pending_frames+0x1f9/0x560 net/ipv6/ip6_output.c:1972
    rawv6_push_pending_frames+0xbe8/0xdf0 net/ipv6/raw.c:582
    rawv6_sendmsg+0x2b66/0x2e70 net/ipv6/raw.c:920
    inet_sendmsg+0x105/0x190 net/ipv4/af_inet.c:847
    sock_sendmsg_nosec net/socket.c:730 [inline]
    __sock_sendmsg net/socket.c:745 [inline]
    ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2584
    ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2638
    __sys_sendmsg net/socket.c:2667 [inline]
    __do_sys_sendmsg net/socket.c:2676 [inline]
    __se_sys_sendmsg net/socket.c:2674 [inline]
    __x64_sys_sendmsg+0x307/0x490 net/socket.c:2674
    do_syscall_x64 arch/x86/entry/common.c:52 [inline]
    do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83
    entry_SYSCALL_64_after_hwframe+0x63/0x6b
    
    Uninit was created at:
    slab_post_alloc_hook+0x129/0xa70 mm/slab.h:768
    slab_alloc_node mm/slub.c:3478 [inline]
    __kmem_cache_alloc_node+0x5c9/0x970 mm/slub.c:3517
    __do_kmalloc_node mm/slab_common.c:1006 [inline]
    __kmalloc_node_track_caller+0x118/0x3c0 mm/slab_common.c:1027
    kmalloc_reserve+0x249/0x4a0 net/core/skbuff.c:582
    pskb_expand_head+0x226/0x1a00 net/core/skbuff.c:2098
    __pskb_pull_tail+0x13b/0x2310 net/core/skbuff.c:2655
    pskb_may_pull_reason include/linux/skbuff.h:2673 [inline]
    pskb_may_pull include/linux/skbuff.h:2681 [inline]
    ip6_tnl_parse_tlv_enc_lim+0x901/0xbb0 net/ipv6/ip6_tunnel.c:408
    ipxip6_tnl_xmit net/ipv6/ip6_tunnel.c:1326 [inline]
    ip6_tnl_start_xmit+0xab2/0x1a70 net/ipv6/ip6_tunnel.c:1432
    __netdev_start_xmit include/linux/netdevice.h:4940 [inline]
    netdev_start_xmit include/linux/netdevice.h:4954 [inline]
    xmit_one net/core/dev.c:3548 [inline]
    dev_hard_start_xmit+0x247/0xa10 net/core/dev.c:3564
    __dev_queue_xmit+0x33b8/0x5130 net/core/dev.c:4349
    dev_queue_xmit include/linux/netdevice.h:3134 [inline]
    neigh_connected_output+0x569/0x660 net/core/neighbour.c:1592
    neigh_output include/net/neighbour.h:542 [inline]
    ip6_finish_output2+0x23a9/0x2b30 net/ipv6/ip6_output.c:137
    ip6_finish_output+0x855/0x12b0 net/ipv6/ip6_output.c:222
    NF_HOOK_COND include/linux/netfilter.h:303 [inline]
    ip6_output+0x323/0x610 net/ipv6/ip6_output.c:243
    dst_output include/net/dst.h:451 [inline]
    ip6_local_out+0xe9/0x140 net/ipv6/output_core.c:155
    ip6_send_skb net/ipv6/ip6_output.c:1952 [inline]
    ip6_push_pending_frames+0x1f9/0x560 net/ipv6/ip6_output.c:1972
    rawv6_push_pending_frames+0xbe8/0xdf0 net/ipv6/raw.c:582
    rawv6_sendmsg+0x2b66/0x2e70 net/ipv6/raw.c:920
    inet_sendmsg+0x105/0x190 net/ipv4/af_inet.c:847
    sock_sendmsg_nosec net/socket.c:730 [inline]
    __sock_sendmsg net/socket.c:745 [inline]
    ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2584
    ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2638
    __sys_sendmsg net/socket.c:2667 [inline]
    __do_sys_sendmsg net/socket.c:2676 [inline]
    __se_sys_sendmsg net/socket.c:2674 [inline]
    __x64_sys_sendmsg+0x307/0x490 net/socket.c:2674
    do_syscall_x64 arch/x86/entry/common.c:52 [inline]
    do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83
    entry_SYSCALL_64_after_hwframe+0x63/0x6b
    
    CPU: 0 PID: 7345 Comm: syz-executor.3 Not tainted 6.7.0-rc8-syzkaller-00024-gac865f00af29 #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023
    
    Fixes: fbfa743a9d2a ("ipv6: fix ip6_tnl_parse_tlv_enc_lim()")
    Reported-by: syzbot <syzkaller@xxxxxxxxxxxxxxxx>
    Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Cc: Willem de Bruijn <willemb@xxxxxxxxxx>
    Reviewed-by: Willem de Bruijn <willemb@xxxxxxxxxx>
    Reviewed-by: David Ahern <dsahern@xxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 48a658b541d7..56309c851928 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -404,7 +404,7 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
 	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;
+	u8 nexthdr = ipv6h->nexthdr;
 
 	while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) {
 		struct ipv6_opt_hdr *hdr;
@@ -415,25 +415,25 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
 
 		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)
-				break;
 			optlen = 8;
 		} else if (nexthdr == NEXTHDR_AUTH) {
 			optlen = (hdr->hdrlen + 2) << 2;
 		} else {
 			optlen = ipv6_optlen(hdr);
 		}
-		/* cache hdr->nexthdr, since pskb_may_pull() might
-		 * invalidate hdr
-		 */
-		next = hdr->nexthdr;
-		if (nexthdr == NEXTHDR_DEST) {
-			u16 i = 2;
 
-			/* Remember : hdr is no longer valid at this point. */
-			if (!pskb_may_pull(skb, off + optlen))
+		if (!pskb_may_pull(skb, off + optlen))
+			break;
+
+		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)
 				break;
+		}
+		if (nexthdr == NEXTHDR_DEST) {
+			u16 i = 2;
 
 			while (1) {
 				struct ipv6_tlv_tnl_enc_lim *tel;
@@ -454,7 +454,7 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
 					i++;
 			}
 		}
-		nexthdr = next;
+		nexthdr = hdr->nexthdr;
 		off += optlen;
 	}
 	return 0;




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux