Skip to content
  • Gianluca Borello's avatar
    bpf: change bpf_perf_event_output arg5 type to ARG_CONST_SIZE_OR_ZERO · a60dd35d
    Gianluca Borello authored
    Commit 9fd29c08
    
     ("bpf: improve verifier ARG_CONST_SIZE_OR_ZERO
    semantics") relaxed the treatment of ARG_CONST_SIZE_OR_ZERO due to the way
    the compiler generates optimized BPF code when checking boundaries of an
    argument from C code. A typical example of this optimized code can be
    generated using the bpf_perf_event_output helper when operating on variable
    memory:
    
    /* len is a generic scalar */
    if (len > 0 && len <= 0x7fff)
            bpf_perf_event_output(ctx, &perf_map, 0, buf, len);
    
    110: (79) r5 = *(u64 *)(r10 -40)
    111: (bf) r1 = r5
    112: (07) r1 += -1
    113: (25) if r1 > 0x7ffe goto pc+6
    114: (bf) r1 = r6
    115: (18) r2 = 0xffff94e5f166c200
    117: (b7) r3 = 0
    118: (bf) r4 = r7
    119: (85) call bpf_perf_event_output#25
    R5 min value is negative, either use unsigned or 'var &= const'
    
    With this code, the verifier loses track of the variable.
    
    Replacing arg5 with ARG_CONST_SIZE_OR_ZERO is thus desirable since it
    avoids this quite common case which leads to usability issues, and the
    compiler generates code that the verifier can more easily test:
    
    if (len <= 0x7fff)
            bpf_perf_event_output(ctx, &perf_map, 0, buf, len);
    
    or
    
    bpf_perf_event_output(ctx, &perf_map, 0, buf, len & 0x7fff);
    
    No changes to the bpf_perf_event_output helper are necessary since it can
    handle a case where size is 0, and an empty frame is pushed.
    
    Reported-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    Signed-off-by: default avatarGianluca Borello <g.borello@gmail.com>
    Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Acked-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    a60dd35d