bpf: Prune verifier diagnostics when switching paths

Save the diagnostic event-log position with each verifier stack entry and
reset the environment-owned stream together with the normal verifier log
when a queued state is popped. Also reset the diagnostic stream after
successful subprogram verification even when level-2 logging preserves the
normal verifier log.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://patch.msgid.link/20260815064612.378577-5-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
This commit is contained in:
Kumar Kartikeya Dwivedi 2026-08-15 08:45:59 +02:00 committed by Eduard Zingerman
parent daf8248701
commit a6debd5f25

View File

@ -194,6 +194,7 @@ struct bpf_verifier_stack_elem {
struct bpf_verifier_stack_elem *next;
/* length of verifier log at the time this state was pushed on stack */
u32 log_pos;
u64 diag_log_pos;
};
#define BPF_COMPLEXITY_LIMIT_JMP_SEQ 8192
@ -1700,6 +1701,7 @@ static int pop_stack(struct bpf_verifier_env *env, int *prev_insn_idx,
err = bpf_copy_verifier_state(cur, &head->st);
if (err)
return err;
bpf_diag_event_log_restore(env, head->diag_log_pos);
}
if (pop_log)
bpf_vlog_reset(&env->log, head->log_pos);
@ -1743,6 +1745,7 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env,
elem->prev_insn_idx = prev_insn_idx;
elem->next = env->head;
elem->log_pos = env->log.end_pos;
elem->diag_log_pos = bpf_diag_event_log_save(env);
env->head = elem;
env->stack_size++;
err = bpf_copy_verifier_state(&elem->st, cur);
@ -2264,6 +2267,7 @@ static struct bpf_verifier_state *push_async_cb(struct bpf_verifier_env *env,
elem->prev_insn_idx = prev_insn_idx;
elem->next = env->head;
elem->log_pos = env->log.end_pos;
elem->diag_log_pos = bpf_diag_event_log_save(env);
env->head = elem;
env->stack_size++;
if (env->stack_size > BPF_COMPLEXITY_LIMIT_JMP_SEQ) {
@ -18635,8 +18639,11 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
ret = do_check(env);
out:
account_current_path(env);
if (!ret && pop_log)
bpf_vlog_reset(&env->log, 0);
if (!ret) {
if (pop_log)
bpf_vlog_reset(&env->log, 0);
bpf_diag_event_log_restore(env, 0);
}
free_states(env);
/*