• Alexei Starovoitov's avatar
    bpf: teach verifier to recognize zero initialized stack · cc2b14d5
    Alexei Starovoitov authored
    programs with function calls are often passing various
    pointers via stack. When all calls are inlined llvm
    flattens stack accesses and optimizes away extra branches.
    When functions are not inlined it becomes the job of
    the verifier to recognize zero initialized stack to avoid
    exploring paths that program will not take.
    The following program would fail otherwise:
    
    ptr = &buffer_on_stack;
    *ptr = 0;
    ...
    func_call(.., ptr, ...) {
      if (..)
        *ptr = bpf_map_lookup();
    }
    ...
    if (*ptr != 0) {
      // Access (*ptr)->field is valid.
      // Without stack_zero tracking such (*ptr)->field access
      // will be rejected
    }
    
    since stack slots are no longer uniform invalid | spill | misc
    add liveness marking to all slots, but do it in 8 byte chunks.
    So if nothing was read or written in [fp-16, fp-9] range
    it will be marked as LIVE_NONE.
    If any byte in that range was read, it will be marked LIVE_READ
    and stacksafe() check will perform byte-by-byte verification.
    If all bytes in the range were written the slot will be
    marked as LIVE_WRITTEN.
    This significantly speeds up state equality comparison
    and reduces total number of states processed.
    
                        before   after
    bpf_lb-DLB_L3.o       2051    2003
    bpf_lb-DLB_L4.o       3287    3164
    bpf_lb-DUNKNOWN.o     1080    1080
    bpf_lxc-DDROP_ALL.o   24980   12361
    bpf_lxc-DUNKNOWN.o    34308   16605
    bpf_netdev.o          15404   10962
    bpf_overlay.o         7191    6679
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Acked-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    cc2b14d5
verifier.c 153 KB