• Gianluca Borello's avatar
    bpf: change bpf_probe_read_str arg2 type to ARG_CONST_SIZE_OR_ZERO · 5c4e1201
    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_probe_read_str helper when operating on variable
    memory:
    
    /* len is a generic scalar */
    if (len > 0 && len <= 0x7fff)
            bpf_probe_read_str(p, len, s);
    
    251: (79) r1 = *(u64 *)(r10 -88)
    252: (07) r1 += -1
    253: (25) if r1 > 0x7ffe goto pc-42
    254: (bf) r1 = r7
    255: (79) r2 = *(u64 *)(r10 -88)
    256: (bf) r8 = r4
    257: (85) call bpf_probe_read_str#45
    R2 min value is negative, either use unsigned or 'var &= const'
    
    With this code, the verifier loses track of the variable.
    
    Replacing arg2 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_probe_read_str(p, len, s);
    
    or
    
    bpf_probe_read_str(p, len & 0x7fff, s);
    
    No changes to the bpf_probe_read_str helper are necessary since
    strncpy_from_unsafe itself immediately returns if the size passed is 0.
    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>
    5c4e1201
bpf_trace.c 21.5 KB