On Mon, Jul 17, 2023 at 9:15 AM Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> wrote: > > 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: 7ddc80a476c2 ("bpf: Teach stack depth check about async callbacks.") > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> Applied. Thanks