On Wed, 2023-11-22 at 13:31 -0800, Andrii Nakryiko wrote: > Slightly change BPF verifier logic around eagerness and order of global > subprog validation. Instead of going over every global subprog eagerly > and validating it before main (entry) BPF program is verified, turn it > around. Validate main program first, mark subprogs that were called from > main program for later verification, but otherwise assume it is valid. > Afterwards, go over marked global subprogs and validate those, > potentially marking some more global functions as being called. Continue > this process until all (transitively) callable global subprogs are > validated. It's a BFS traversal at its heart and will always converge. > > This is an important change because it allows to feature-gate some > subprograms that might not be verifiable on some older kernel, depending > on supported set of features. > [...] > > Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx> Acked-by: Eduard Zingerman <eddyz87@xxxxxxxx> [...] > @@ -19761,14 +19772,26 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog, bool is_ex > static int do_check_subprogs(struct bpf_verifier_env *env) > { > struct bpf_prog_aux *aux = env->prog->aux; > - int i, ret; > + struct bpf_func_info_aux *sub_aux; > + int i, ret, new_cnt; > > if (!aux->func_info) > return 0; > > + /* exception callback is presumed to be always called */ > + if (env->exception_callback_subprog) > + subprog_aux(env, env->exception_callback_subprog)->called = true; > + > +again: Nit: I'd use an explicit loop and a separate function here, but kernel people like their gotos... [...]