• Xu Yu's avatar
    bpf: do not restore dst_reg when cur_state is freed · 046098f0
    Xu Yu authored
    commit 0803278b upstream.
    
    Syzkaller hit 'KASAN: use-after-free Write in sanitize_ptr_alu' bug.
    
    Call trace:
    
      dump_stack+0xbf/0x12e
      print_address_description+0x6a/0x280
      kasan_report+0x237/0x360
      sanitize_ptr_alu+0x85a/0x8d0
      adjust_ptr_min_max_vals+0x8f2/0x1ca0
      adjust_reg_min_max_vals+0x8ed/0x22e0
      do_check+0x1ca6/0x5d00
      bpf_check+0x9ca/0x2570
      bpf_prog_load+0xc91/0x1030
      __se_sys_bpf+0x61e/0x1f00
      do_syscall_64+0xc8/0x550
      entry_SYSCALL_64_after_hwframe+0x49/0xbe
    
    Fault injection trace:
    
      kfree+0xea/0x290
      free_func_state+0x4a/0x60
      free_verifier_state+0x61/0xe0
      push_stack+0x216/0x2f0	          <- inject failslab
      sanitize_ptr_alu+0x2b1/0x8d0
      adjust_ptr_min_max_vals+0x8f2/0x1ca0
      adjust_reg_min_max_vals+0x8ed/0x22e0
      do_check+0x1ca6/0x5d00
      bpf_check+0x9ca/0x2570
      bpf_prog_load+0xc91/0x1030
      __se_sys_bpf+0x61e/0x1f00
      do_syscall_64+0xc8/0x550
      entry_SYSCALL_64_after_hwframe+0x49/0xbe
    
    When kzalloc() fails in push_stack(), free_verifier_state() will free
    current verifier state. As push_stack() returns, dst_reg was restored
    if ptr_is_dst_reg is false. However, as member of the cur_state,
    dst_reg is also freed, and error occurs when dereferencing dst_reg.
    Simply fix it by testing ret of push_stack() before restoring dst_reg.
    
    Fixes: 979d63d5 ("bpf: prevent out of bounds speculation on pointer arithmetic")
    Signed-off-by: 's avatarXu Yu <xuyu@linux.alibaba.com>
    Signed-off-by: 's avatarDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    046098f0
Name
Last commit
Last update
..
Makefile Loading commit data...
arraymap.c Loading commit data...
bpf_lru_list.c Loading commit data...
bpf_lru_list.h Loading commit data...
btf.c Loading commit data...
cgroup.c Loading commit data...
core.c Loading commit data...
cpumap.c Loading commit data...
devmap.c Loading commit data...
disasm.c Loading commit data...
disasm.h Loading commit data...
hashtab.c Loading commit data...
helpers.c Loading commit data...
inode.c Loading commit data...
local_storage.c Loading commit data...
lpm_trie.c Loading commit data...
map_in_map.c Loading commit data...
map_in_map.h Loading commit data...
offload.c Loading commit data...
percpu_freelist.c Loading commit data...
percpu_freelist.h Loading commit data...
queue_stack_maps.c Loading commit data...
reuseport_array.c Loading commit data...
stackmap.c Loading commit data...
syscall.c Loading commit data...
tnum.c Loading commit data...
verifier.c Loading commit data...
xskmap.c Loading commit data...