On Thu, 2024-02-01 at 04:20 +0000, Kumar Kartikeya Dwivedi wrote: > Global subprogs are not descended during symbolic execution, but we > summarized whether they can throw an exception (reachable from another > exception throwing subprog) in mark_exception_reachable_subprogs added > by the previous patch. [...] > Fixes: f18b03fabaa9 ("bpf: Implement BPF exceptions") > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> > --- Acked-by: Eduard Zingerman <eddyz87@xxxxxxxxx> Also, did you consider global subprograms that always throw? E.g. do some logging and unconditionally call bpf_throw(). [...] > @@ -9505,6 +9515,9 @@ static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn, > mark_reg_unknown(env, caller->regs, BPF_REG_0); > caller->regs[BPF_REG_0].subreg_def = DEF_NOT_SUBREG; > > + if (env->cur_state->global_subprog_call_exception) > + verbose(env, "Func#%d ('%s') may throw exception, exploring program path where exception is thrown\n", > + subprog, sub_name); Nit: Maybe move this log entry to do_check? It would be printed right before returning to do_check() anyways. Maybe add a log level check? > /* continue with next insn after call */ > return 0; > } [...] > @@ -17675,6 +17692,11 @@ static int do_check(struct bpf_verifier_env *env) > } > if (insn->src_reg == BPF_PSEUDO_CALL) { > err = check_func_call(env, insn, &env->insn_idx); > + if (!err && env->cur_state->global_subprog_call_exception) { > + env->cur_state->global_subprog_call_exception = false; > + exception_exit = true; > + goto process_bpf_exit_full; > + } > } else if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) { > err = check_kfunc_call(env, insn, &env->insn_idx); > if (!err && is_bpf_throw_kfunc(insn)) {