• Hao Luo's avatar
    bpf: Fix checking PTR_TO_BTF_ID in check_mem_access · bff61f6f
    Hao Luo authored
    With the introduction of MEM_USER in
    
     commit c6f1bfe8 ("bpf: reject program if a __user tagged memory accessed in kernel way")
    
    PTR_TO_BTF_ID can be combined with a MEM_USER tag. Therefore, most
    likely, when we compare reg_type against PTR_TO_BTF_ID, we want to use
    the reg's base_type. Previously the check in check_mem_access() wants
    to say: if the reg is BTF_ID but not NULL, the execution flow falls
    into the 'then' branch. But now a reg of (BTF_ID | MEM_USER), which
    should go into the 'then' branch, goes into the 'else'.
    
    The end results before and after this patch are the same: regs tagged
    with MEM_USER get rejected, but not in a way we intended. So fix the
    condition, the error message now is correct.
    
    Before (log from commit 696c3901):
    
      $ ./test_progs -v -n 22/3
      ...
      libbpf: prog 'test_user1': BPF program load failed: Permission denied
      libbpf: prog 'test_user1': -- BEGIN PROG LOAD LOG --
      R1 type=ctx expected=fp
      0: R1=ctx(id=0,off=0,imm=0) R10=fp0
      ; int BPF_PROG(test_user1, struct bpf_testmod_btf_type_tag_1 *arg)
      0: (79) r1 = *(u64 *)(r1 +0)
      func 'bpf_testmod_test_btf_type_tag_user_1' arg0 has btf_id 136561 type STRUCT 'bpf_testmod_btf_type_tag_1'
      1: R1_w=user_ptr_bpf_testmod_btf_type_tag_1(id=0,off=0,imm=0)
      ; g = arg->a;
      1: (61) r1 = *(u32 *)(r1 +0)
      R1 invalid mem access 'user_ptr_'
    
    Now:
    
      libbpf: prog 'test_user1': BPF program load failed: Permission denied
      libbpf: prog 'test_user1': -- BEGIN PROG LOAD LOG --
      R1 type=ctx expected=fp
      0: R1=ctx(id=0,off=0,imm=0) R10=fp0
      ; int BPF_PROG(test_user1, struct bpf_testmod_btf_type_tag_1 *arg)
      0: (79) r1 = *(u64 *)(r1 +0)
      func 'bpf_testmod_test_btf_type_tag_user_1' arg0 has btf_id 104036 type STRUCT 'bpf_testmod_btf_type_tag_1'
      1: R1_w=user_ptr_bpf_testmod_btf_type_tag_1(id=0,ref_obj_id=0,off=0,imm=0)
      ; g = arg->a;
      1: (61) r1 = *(u32 *)(r1 +0)
      R1 is ptr_bpf_testmod_btf_type_tag_1 access user memory: off=0
    
    Note the error message for the reason of rejection.
    
    Fixes: c6f1bfe8 ("bpf: reject program if a __user tagged memory accessed in kernel way")
    Signed-off-by: default avatarHao Luo <haoluo@google.com>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Acked-by: default avatarYonghong Song <yhs@fb.com>
    Link: https://lore.kernel.org/bpf/20220304191657.981240-2-haoluo@google.com
    bff61f6f
verifier.c 414 KB