• Alexei Starovoitov's avatar
    bpf: Implement verifier support for validation of async callbacks. · bfc6bb74
    Alexei Starovoitov authored
    bpf_for_each_map_elem() and bpf_timer_set_callback() helpers are relying on
    PTR_TO_FUNC infra in the verifier to validate addresses to subprograms
    and pass them into the helpers as function callbacks.
    In case of bpf_for_each_map_elem() the callback is invoked synchronously
    and the verifier treats it as a normal subprogram call by adding another
    bpf_func_state and new frame in __check_func_call().
    bpf_timer_set_callback() doesn't invoke the callback directly.
    The subprogram will be called asynchronously from bpf_timer_cb().
    Teach the verifier to validate such async callbacks as special kind
    of jump by pushing verifier state into stack and let pop_stack() process it.
    
    Special care needs to be taken during state pruning.
    The call insn doing bpf_timer_set_callback has to be a prune_point.
    Otherwise short timer callbacks might not have prune points in front of
    bpf_timer_set_callback() which means is_state_visited() will be called
    after this call insn is processed in __check_func_call(). Which means that
    another async_cb state will be pushed to be walked later and the verifier
    will eventually hit BPF_COMPLEXITY_LIMIT_JMP_SEQ limit.
    Since push_async_cb() looks like another push_stack() branch the
    infinite loop detection will trigger false positive. To recognize
    this case mark such states as in_async_callback_fn.
    To distinguish infinite loop in async callback vs the same callback called
    with different arguments for different map and timer add async_entry_cnt
    to bpf_func_state.
    
    Enforce return zero from async callbacks.
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
    Acked-by: default avatarToke Høiland-Jørgensen <toke@redhat.com>
    Link: https://lore.kernel.org/bpf/20210715005417.78572-9-alexei.starovoitov@gmail.com
    bfc6bb74
helpers.c 34.7 KB