Skip to content
  • Daniel Borkmann's avatar
    bpf: fix context access in tracing progs on 32 bit archs · bc23105c
    Daniel Borkmann authored
    
    
    Wang reported that all the testcases for BPF_PROG_TYPE_PERF_EVENT
    program type in test_verifier report the following errors on x86_32:
    
      172/p unpriv: spill/fill of different pointers ldx FAIL
      Unexpected error message!
      0: (bf) r6 = r10
      1: (07) r6 += -8
      2: (15) if r1 == 0x0 goto pc+3
      R1=ctx(id=0,off=0,imm=0) R6=fp-8,call_-1 R10=fp0,call_-1
      3: (bf) r2 = r10
      4: (07) r2 += -76
      5: (7b) *(u64 *)(r6 +0) = r2
      6: (55) if r1 != 0x0 goto pc+1
      R1=ctx(id=0,off=0,imm=0) R2=fp-76,call_-1 R6=fp-8,call_-1 R10=fp0,call_-1 fp-8=fp
      7: (7b) *(u64 *)(r6 +0) = r1
      8: (79) r1 = *(u64 *)(r6 +0)
      9: (79) r1 = *(u64 *)(r1 +68)
      invalid bpf_context access off=68 size=8
    
      378/p check bpf_perf_event_data->sample_period byte load permitted FAIL
      Failed to load prog 'Permission denied'!
      0: (b7) r0 = 0
      1: (71) r0 = *(u8 *)(r1 +68)
      invalid bpf_context access off=68 size=1
    
      379/p check bpf_perf_event_data->sample_period half load permitted FAIL
      Failed to load prog 'Permission denied'!
      0: (b7) r0 = 0
      1: (69) r0 = *(u16 *)(r1 +68)
      invalid bpf_context access off=68 size=2
    
      380/p check bpf_perf_event_data->sample_period word load permitted FAIL
      Failed to load prog 'Permission denied'!
      0: (b7) r0 = 0
      1: (61) r0 = *(u32 *)(r1 +68)
      invalid bpf_context access off=68 size=4
    
      381/p check bpf_perf_event_data->sample_period dword load permitted FAIL
      Failed to load prog 'Permission denied'!
      0: (b7) r0 = 0
      1: (79) r0 = *(u64 *)(r1 +68)
      invalid bpf_context access off=68 size=8
    
    Reason is that struct pt_regs on x86_32 doesn't fully align to 8 byte
    boundary due to its size of 68 bytes. Therefore, bpf_ctx_narrow_access_ok()
    will then bail out saying that off & (size_default - 1) which is 68 & 7
    doesn't cleanly align in the case of sample_period access from struct
    bpf_perf_event_data, hence verifier wrongly thinks we might be doing an
    unaligned access here though underlying arch can handle it just fine.
    Therefore adjust this down to machine size and check and rewrite the
    offset for narrow access on that basis. We also need to fix corresponding
    pe_prog_is_valid_access(), since we hit the check for off % size != 0
    (e.g. 68 % 8 -> 4) in the first and last test. With that in place, progs
    for tracing work on x86_32.
    
    Reported-by: default avatarWang YanQing <udknight@gmail.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Tested-by: default avatarWang YanQing <udknight@gmail.com>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    bc23105c