• D
    bpf: fix panic due to oob in bpf_prog_test_run_skb · 6e6fddc7
    Daniel Borkmann 提交于
    sykzaller triggered several panics similar to the below:
    
      [...]
      [  248.851531] BUG: KASAN: use-after-free in _copy_to_user+0x5c/0x90
      [  248.857656] Read of size 985 at addr ffff8808017ffff2 by task a.out/1425
      [...]
      [  248.865902] CPU: 1 PID: 1425 Comm: a.out Not tainted 4.18.0-rc4+ #13
      [  248.865903] Hardware name: Supermicro SYS-5039MS-H12TRF/X11SSE-F, BIOS 2.1a 03/08/2018
      [  248.865905] Call Trace:
      [  248.865910]  dump_stack+0xd6/0x185
      [  248.865911]  ? show_regs_print_info+0xb/0xb
      [  248.865913]  ? printk+0x9c/0xc3
      [  248.865915]  ? kmsg_dump_rewind_nolock+0xe4/0xe4
      [  248.865919]  print_address_description+0x6f/0x270
      [  248.865920]  kasan_report+0x25b/0x380
      [  248.865922]  ? _copy_to_user+0x5c/0x90
      [  248.865924]  check_memory_region+0x137/0x190
      [  248.865925]  kasan_check_read+0x11/0x20
      [  248.865927]  _copy_to_user+0x5c/0x90
      [  248.865930]  bpf_test_finish.isra.8+0x4f/0xc0
      [  248.865932]  bpf_prog_test_run_skb+0x6a0/0xba0
      [...]
    
    After scrubbing the BPF prog a bit from the noise, turns out it called
    bpf_skb_change_head() for the lwt_xmit prog with headroom of 2. Nothing
    wrong in that, however, this was run with repeat >> 0 in bpf_prog_test_run_skb()
    and the same skb thus keeps changing until the pskb_expand_head() called
    from skb_cow() keeps bailing out in atomic alloc context with -ENOMEM.
    So upon return we'll basically have 0 headroom left yet blindly do the
    __skb_push() of 14 bytes and keep copying data from there in bpf_test_finish()
    out of bounds. Fix to check if we have enough headroom and if pskb_expand_head()
    fails, bail out with error.
    
    Another bug independent of this fix (but related in triggering above) is
    that BPF_PROG_TEST_RUN should be reworked to reset the skb/xdp buffer to
    it's original state from input as otherwise repeating the same test in a
    loop won't work for benchmarking when underlying input buffer is getting
    changed by the prog each time and reused for the next run leading to
    unexpected results.
    
    Fixes: 1cf1cae9 ("bpf: introduce BPF_PROG_TEST_RUN command")
    Reported-by: syzbot+709412e651e55ed96498@syzkaller.appspotmail.com
    Reported-by: syzbot+54f39d6ab58f39720a55@syzkaller.appspotmail.com
    Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
    6e6fddc7
test_verifier.c 379.3 KB