| From: Eric Dumazet <edumazet@google.com> |
| Date: Sat, 12 May 2018 02:49:30 -0700 |
| Subject: xfrm6: avoid potential infinite loop in _decode_session6() |
| |
| commit d9f92772e8ec388d070752ee8f187ef8fa18621f upstream. |
| |
| syzbot found a way to trigger an infinitie loop by overflowing |
| @offset variable that has been forced to use u16 for some very |
| obscure reason in the past. |
| |
| We probably want to look at NEXTHDR_FRAGMENT handling which looks |
| wrong, in a separate patch. |
| |
| In net-next, we shall try to use skb_header_pointer() instead of |
| pskb_may_pull(). |
| |
| watchdog: BUG: soft lockup - CPU#1 stuck for 134s! [syz-executor738:4553] |
| Modules linked in: |
| irq event stamp: 13885653 |
| hardirqs last enabled at (13885652): [<ffffffff878009d5>] restore_regs_and_return_to_kernel+0x0/0x2b |
| hardirqs last disabled at (13885653): [<ffffffff87800905>] interrupt_entry+0xb5/0xf0 arch/x86/entry/entry_64.S:625 |
| softirqs last enabled at (13614028): [<ffffffff84df0809>] tun_napi_alloc_frags drivers/net/tun.c:1478 [inline] |
| softirqs last enabled at (13614028): [<ffffffff84df0809>] tun_get_user+0x1dd9/0x4290 drivers/net/tun.c:1825 |
| softirqs last disabled at (13614032): [<ffffffff84df1b6f>] tun_get_user+0x313f/0x4290 drivers/net/tun.c:1942 |
| CPU: 1 PID: 4553 Comm: syz-executor738 Not tainted 4.17.0-rc3+ #40 |
| Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 |
| RIP: 0010:check_kcov_mode kernel/kcov.c:67 [inline] |
| RIP: 0010:__sanitizer_cov_trace_pc+0x20/0x50 kernel/kcov.c:101 |
| RSP: 0018:ffff8801d8cfe250 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff13 |
| RAX: ffff8801d88a8080 RBX: ffff8801d7389e40 RCX: 0000000000000006 |
| RDX: 0000000000000000 RSI: ffffffff868da4ad RDI: ffff8801c8a53277 |
| RBP: ffff8801d8cfe250 R08: ffff8801d88a8080 R09: ffff8801d8cfe3e8 |
| R10: ffffed003b19fc87 R11: ffff8801d8cfe43f R12: ffff8801c8a5327f |
| R13: 0000000000000000 R14: ffff8801c8a4e5fe R15: ffff8801d8cfe3e8 |
| FS: 0000000000d88940(0000) GS:ffff8801daf00000(0000) knlGS:0000000000000000 |
| CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 |
| CR2: ffffffffff600400 CR3: 00000001acab3000 CR4: 00000000001406e0 |
| DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 |
| DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 |
| Call Trace: |
| _decode_session6+0xc1d/0x14f0 net/ipv6/xfrm6_policy.c:150 |
| __xfrm_decode_session+0x71/0x140 net/xfrm/xfrm_policy.c:2368 |
| xfrm_decode_session_reverse include/net/xfrm.h:1213 [inline] |
| icmpv6_route_lookup+0x395/0x6e0 net/ipv6/icmp.c:372 |
| icmp6_send+0x1982/0x2da0 net/ipv6/icmp.c:551 |
| icmpv6_send+0x17a/0x300 net/ipv6/ip6_icmp.c:43 |
| ip6_input_finish+0x14e1/0x1a30 net/ipv6/ip6_input.c:305 |
| NF_HOOK include/linux/netfilter.h:288 [inline] |
| ip6_input+0xe1/0x5e0 net/ipv6/ip6_input.c:327 |
| dst_input include/net/dst.h:450 [inline] |
| ip6_rcv_finish+0x29c/0xa10 net/ipv6/ip6_input.c:71 |
| NF_HOOK include/linux/netfilter.h:288 [inline] |
| ipv6_rcv+0xeb8/0x2040 net/ipv6/ip6_input.c:208 |
| __netif_receive_skb_core+0x2468/0x3650 net/core/dev.c:4646 |
| __netif_receive_skb+0x2c/0x1e0 net/core/dev.c:4711 |
| netif_receive_skb_internal+0x126/0x7b0 net/core/dev.c:4785 |
| napi_frags_finish net/core/dev.c:5226 [inline] |
| napi_gro_frags+0x631/0xc40 net/core/dev.c:5299 |
| tun_get_user+0x3168/0x4290 drivers/net/tun.c:1951 |
| tun_chr_write_iter+0xb9/0x154 drivers/net/tun.c:1996 |
| call_write_iter include/linux/fs.h:1784 [inline] |
| do_iter_readv_writev+0x859/0xa50 fs/read_write.c:680 |
| do_iter_write+0x185/0x5f0 fs/read_write.c:959 |
| vfs_writev+0x1c7/0x330 fs/read_write.c:1004 |
| do_writev+0x112/0x2f0 fs/read_write.c:1039 |
| __do_sys_writev fs/read_write.c:1112 [inline] |
| __se_sys_writev fs/read_write.c:1109 [inline] |
| __x64_sys_writev+0x75/0xb0 fs/read_write.c:1109 |
| do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287 |
| entry_SYSCALL_64_after_hwframe+0x49/0xbe |
| |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Cc: Steffen Klassert <steffen.klassert@secunet.com> |
| Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com> |
| Reported-by: syzbot+0053c8...@syzkaller.appspotmail.com |
| Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> |
| [bwh: Backported to 3.16: adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| net/ipv6/xfrm6_policy.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/net/ipv6/xfrm6_policy.c |
| +++ b/net/ipv6/xfrm6_policy.c |
| @@ -128,7 +128,7 @@ _decode_session6(struct sk_buff *skb, st |
| { |
| struct flowi6 *fl6 = &fl->u.ip6; |
| int onlyproto = 0; |
| - u16 offset = skb_network_header_len(skb); |
| + u32 offset = skb_network_header_len(skb); |
| const struct ipv6hdr *hdr = ipv6_hdr(skb); |
| struct ipv6_opt_hdr *exthdr; |
| const unsigned char *nh = skb_network_header(skb); |