Re: invalid opcode in ip_do_fragment

From: Willem de Bruijn
Date: Sat Nov 24 2018 - 12:21:12 EST


On Sat, Nov 24, 2018 at 2:11 AM syzbot
<syzbot+865704dc4f7ff5d1a04b@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> Hello,
>
> syzbot found the following crash on:
>
> HEAD commit: 92b419289cee Merge tag 'riscv-for-linus-4.20-rc4' of git:/..
> git tree: upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=12243093400000
> kernel config: https://syzkaller.appspot.com/x/.config?x=73e2bc0cb6463446
> dashboard link: https://syzkaller.appspot.com/bug?extid=865704dc4f7ff5d1a04b
> compiler: gcc (GCC) 8.0.1 20180413 (experimental)
>
> Unfortunately, I don't have any reproducer for this crash yet.
>
> IMPORTANT: if you fix the bug, please add the following tag to the commit:
> Reported-by: syzbot+865704dc4f7ff5d1a04b@xxxxxxxxxxxxxxxxxxxxxxxxx
>
> invalid opcode: 0000 [#1] PREEMPT SMP KASAN
> CPU: 0 PID: 21078 Comm: syz-executor1 Not tainted 4.20.0-rc3+ #344
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> Google 01/01/2011
> RIP: 0010:ip_do_fragment+0x2447/0x2ad0 net/ipv4/ip_output.c:776
> Code: ff 48 89 cf e8 2a 36 23 fb e9 dc ea ff ff 48 89 df e8 5d 36 23 fb e9
> 02 e7 ff ff e8 b3 36 23 fb e9 97 e6 ff ff e8 29 e7 df fa <0f> 0b 4c 89 f7
> e8 ff 35 23 fb e9 2f e6 ff ff 4c 89 e7 e8 f2 35 23
> RSP: 0018:ffff88818232e7b8 EFLAGS: 00010246
> RAX: 0000000000040000 RBX: ffff8881d3af0800 RCX: ffffc9000c0db000
> RDX: 0000000000040000 RSI: ffffffff869fa3c7 RDI: 0000000000000005
> RBP: ffff88818232e990 R08: ffff88816ba06580 R09: ffffed10342f86ca
> R10: ffffed10342f86cc R11: ffff8881a17c3663 R12: ffff8881d3af08c4
> R13: 00000000fffffff2 R14: ffff8881d3af08d0 R15: dffffc0000000000
> FS: 00007fa003fcd700(0000) GS:ffff8881dae00000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00000000004ccd10 CR3: 0000000199f89000 CR4: 00000000001426f0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> Call Trace:
> ip_fragment.constprop.50+0x179/0x240 net/ipv4/ip_output.c:549
> ip_finish_output+0x6b4/0xfa0 net/ipv4/ip_output.c:315
> NF_HOOK_COND include/linux/netfilter.h:278 [inline]
> ip_output+0x21d/0x8d0 net/ipv4/ip_output.c:405
> dst_output include/net/dst.h:444 [inline]
> ip_local_out+0xc5/0x1b0 net/ipv4/ip_output.c:124
> iptunnel_xmit+0x63b/0x9c0 net/ipv4/ip_tunnel_core.c:91
> ip_tunnel_xmit+0x15b8/0x3c04 net/ipv4/ip_tunnel.c:787
> __gre_xmit+0x5e1/0x980 net/ipv4/ip_gre.c:451
> ipgre_xmit+0x3e7/0xba0 net/ipv4/ip_gre.c:705
> __netdev_start_xmit include/linux/netdevice.h:4356 [inline]
> netdev_start_xmit include/linux/netdevice.h:4365 [inline]
> xmit_one net/core/dev.c:3252 [inline]
> dev_hard_start_xmit+0x295/0xc80 net/core/dev.c:3268
> __dev_queue_xmit+0x2f71/0x3ad0 net/core/dev.c:3838
> dev_queue_xmit+0x17/0x20 net/core/dev.c:3871
> __bpf_tx_skb net/core/filter.c:2017 [inline]
> __bpf_redirect_common net/core/filter.c:2055 [inline]
> __bpf_redirect+0x5cf/0xb20 net/core/filter.c:2062
> ____bpf_clone_redirect net/core/filter.c:2095 [inline]
> bpf_clone_redirect+0x2f6/0x490 net/core/filter.c:2067
> bpf_prog_bebbfe2050753572+0x7dd/0x1000

The syzbot dashboard has a longer trace, when looking at the log. This
includes a bpf program and probably bpf_prog_test_run.

ip_output.c +776 is a BUG at this commit

/*
* Copy a block of the IP datagram.
*/
if (skb_copy_bits(skb, ptr, skb_transport_header(skb2), len))
BUG();

Perhaps the BPF program managed to modify the packet in a way that
changed its length.

Either way, a bad packet in the egress path seems like a recoverable
bug that probably should not result in BUG().