• Kumar Kartikeya Dwivedi's avatar
    bpf: Repeat check_max_stack_depth for async callbacks · b5e9ad52
    Kumar Kartikeya Dwivedi authored
    While the check_max_stack_depth function explores call chains emanating
    from the main prog, which is typically enough to cover all possible call
    chains, it doesn't explore those rooted at async callbacks unless the
    async callback will have been directly called, since unlike non-async
    callbacks it skips their instruction exploration as they don't
    contribute to stack depth.
    
    It could be the case that the async callback leads to a callchain which
    exceeds the stack depth, but this is never reachable while only
    exploring the entry point from main subprog. Hence, repeat the check for
    the main subprog *and* all async callbacks marked by the symbolic
    execution pass of the verifier, as execution of the program may begin at
    any of them.
    
    Consider functions with following stack depths:
    main: 256
    async: 256
    foo: 256
    
    main:
        rX = async
        bpf_timer_set_callback(...)
    
    async:
        foo()
    
    Here, async is not descended as it does not contribute to stack depth of
    main (since it is referenced using bpf_pseudo_func and not
    bpf_pseudo_call). However, when async is invoked asynchronously, it will
    end up breaching the MAX_BPF_STACK limit by calling foo.
    
    Hence, in addition to main, we also need to explore call chains
    beginning at all async callback subprogs in a program.
    
    Fixes: 7ddc80a4 ("bpf: Teach stack depth check about async callbacks.")
    Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
    Link: https://lore.kernel.org/r/20230717161530.1238-3-memxor@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    b5e9ad52
verifier.c 573 KB