Skip to content

Commit 1cb0f56

Browse files
pchaignoAlexei Starovoitov
authored and
Alexei Starovoitov
committed
bpf: WARN_ONCE on verifier bugs
Throughout the verifier's logic, there are multiple checks for inconsistent states that should never happen and would indicate a verifier bug. These bugs are typically logged in the verifier logs and sometimes preceded by a WARN_ONCE. This patch reworks these checks to consistently emit a verifier log AND a warning when CONFIG_DEBUG_KERNEL is enabled. The consistent use of WARN_ONCE should help fuzzers (ex. syzkaller) expose any situation where they are actually able to reach one of those buggy verifier states. Acked-by: Andrii Nakryiko <[email protected]> Signed-off-by: Paul Chaignon <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 9325d53 commit 1cb0f56

File tree

4 files changed

+79
-83
lines changed

4 files changed

+79
-83
lines changed

include/linux/bpf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,12 @@ static inline const char *btf_field_type_name(enum btf_field_type type)
346346
}
347347
}
348348

349+
#if IS_ENABLED(CONFIG_DEBUG_KERNEL)
350+
#define BPF_WARN_ONCE(cond, format...) WARN_ONCE(cond, format)
351+
#else
352+
#define BPF_WARN_ONCE(cond, format...) BUILD_BUG_ON_INVALID(cond)
353+
#endif
354+
349355
static inline u32 btf_field_type_size(enum btf_field_type type)
350356
{
351357
switch (type) {

include/linux/bpf_verifier.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,17 @@ __printf(3, 4) void verbose_linfo(struct bpf_verifier_env *env,
839839
u32 insn_off,
840840
const char *prefix_fmt, ...);
841841

842+
#define verifier_bug_if(cond, env, fmt, args...) \
843+
({ \
844+
bool __cond = (cond); \
845+
if (unlikely(__cond)) { \
846+
BPF_WARN_ONCE(1, "verifier bug: " fmt "(" #cond ")\n", ##args); \
847+
bpf_log(&env->log, "verifier bug: " fmt "(" #cond ")\n", ##args); \
848+
} \
849+
(__cond); \
850+
})
851+
#define verifier_bug(env, fmt, args...) verifier_bug_if(1, env, fmt, ##args)
852+
842853
static inline struct bpf_func_state *cur_func(struct bpf_verifier_env *env)
843854
{
844855
struct bpf_verifier_state *cur = env->cur_state;

kernel/bpf/btf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7659,7 +7659,7 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
76597659
return 0;
76607660

76617661
if (!prog->aux->func_info) {
7662-
bpf_log(log, "Verifier bug\n");
7662+
verifier_bug(env, "func_info undefined");
76637663
return -EFAULT;
76647664
}
76657665

@@ -7683,7 +7683,7 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
76837683
tname = btf_name_by_offset(btf, fn_t->name_off);
76847684

76857685
if (prog->aux->func_info_aux[subprog].unreliable) {
7686-
bpf_log(log, "Verifier bug in function %s()\n", tname);
7686+
verifier_bug(env, "unreliable BTF for function %s()", tname);
76877687
return -EFAULT;
76887688
}
76897689
if (prog_type == BPF_PROG_TYPE_EXT)

0 commit comments

Comments
 (0)