xref: /linux/kernel/bpf/diagnostics.h (revision a8f4278353947d019c990a77d574dfd4d1dc9b46)
15ad74616SKumar Kartikeya Dwivedi /* SPDX-License-Identifier: GPL-2.0-only */
25ad74616SKumar Kartikeya Dwivedi /* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
35ad74616SKumar Kartikeya Dwivedi 
45ad74616SKumar Kartikeya Dwivedi #ifndef __BPF_DIAGNOSTICS_H
55ad74616SKumar Kartikeya Dwivedi #define __BPF_DIAGNOSTICS_H
65ad74616SKumar Kartikeya Dwivedi 
7d63284e6SKumar Kartikeya Dwivedi #include <linux/bpf.h>
85ad74616SKumar Kartikeya Dwivedi #include <linux/compiler_attributes.h>
9b9c5d822SKumar Kartikeya Dwivedi #include <linux/stdarg.h>
105ad74616SKumar Kartikeya Dwivedi #include <linux/types.h>
115ad74616SKumar Kartikeya Dwivedi 
125d576462SKumar Kartikeya Dwivedi struct bpf_reference_state;
13af4ea6e2SKumar Kartikeya Dwivedi struct bpf_func_state;
14af4ea6e2SKumar Kartikeya Dwivedi struct bpf_reg_state;
155ad74616SKumar Kartikeya Dwivedi struct bpf_verifier_env;
16956a66e5SKumar Kartikeya Dwivedi struct bpf_verifier_state;
17af4ea6e2SKumar Kartikeya Dwivedi struct btf;
18af4ea6e2SKumar Kartikeya Dwivedi 
192bdc90f5SKumar Kartikeya Dwivedi const char *bpf_diag_fmt_s64_sum(struct bpf_verifier_env *env, s64 value, int addend);
20af4ea6e2SKumar Kartikeya Dwivedi enum bpf_diag_mod_reason {
21af4ea6e2SKumar Kartikeya Dwivedi 	BPF_DIAG_MOD_WRITE,
22af4ea6e2SKumar Kartikeya Dwivedi 	BPF_DIAG_MOD_SPILL,
23af4ea6e2SKumar Kartikeya Dwivedi 	BPF_DIAG_MOD_VAR_WRITE,
24af4ea6e2SKumar Kartikeya Dwivedi 	BPF_DIAG_MOD_REF_RELEASE,
25af4ea6e2SKumar Kartikeya Dwivedi 	BPF_DIAG_MOD_PKT_DATA_CHANGE,
26af4ea6e2SKumar Kartikeya Dwivedi 	BPF_DIAG_MOD_NON_OWN_REF,
27af4ea6e2SKumar Kartikeya Dwivedi 	BPF_DIAG_MOD_CALLER_SAVED,
28af4ea6e2SKumar Kartikeya Dwivedi };
295ad74616SKumar Kartikeya Dwivedi 
30956a66e5SKumar Kartikeya Dwivedi enum bpf_diag_context_kind {
31956a66e5SKumar Kartikeya Dwivedi 	BPF_DIAG_CONTEXT_NONE,
32956a66e5SKumar Kartikeya Dwivedi 	BPF_DIAG_CONTEXT_RCU,
33956a66e5SKumar Kartikeya Dwivedi 	BPF_DIAG_CONTEXT_PREEMPT,
34956a66e5SKumar Kartikeya Dwivedi 	BPF_DIAG_CONTEXT_IRQ,
35956a66e5SKumar Kartikeya Dwivedi 	BPF_DIAG_CONTEXT_LOCK,
36956a66e5SKumar Kartikeya Dwivedi };
37956a66e5SKumar Kartikeya Dwivedi 
38d63284e6SKumar Kartikeya Dwivedi enum bpf_diag_invalid_deref_kind {
39d63284e6SKumar Kartikeya Dwivedi 	BPF_DIAG_DEREF_SCALAR,
40d63284e6SKumar Kartikeya Dwivedi 	BPF_DIAG_DEREF_NULLABLE_PTR,
41d63284e6SKumar Kartikeya Dwivedi 	BPF_DIAG_DEREF_MODIFIED_PTR,
42d63284e6SKumar Kartikeya Dwivedi 	BPF_DIAG_DEREF_INVALID_PTR,
43d63284e6SKumar Kartikeya Dwivedi };
44d63284e6SKumar Kartikeya Dwivedi 
455ad74616SKumar Kartikeya Dwivedi bool bpf_diag_enabled(const struct bpf_verifier_env *env);
46b9c5d822SKumar Kartikeya Dwivedi int bpf_diag_init(struct bpf_verifier_env *env);
47af4ea6e2SKumar Kartikeya Dwivedi void bpf_diag_init_frame(struct bpf_verifier_env *env, struct bpf_func_state *state);
48b9c5d822SKumar Kartikeya Dwivedi char *bpf_diag_fmt_buf(struct bpf_verifier_env *env, size_t size);
49b9c5d822SKumar Kartikeya Dwivedi const char *bpf_diag_vfmt(struct bpf_verifier_env *env, const char *fmt, va_list args)
50b9c5d822SKumar Kartikeya Dwivedi 	__printf(2, 0);
51b9c5d822SKumar Kartikeya Dwivedi const char *bpf_diag_fmt(struct bpf_verifier_env *env, const char *fmt, ...) __printf(2, 3);
52af4ea6e2SKumar Kartikeya Dwivedi const char *bpf_diag_fmt_btf_type(struct bpf_verifier_env *env, const struct btf *btf, u32 type_id);
53d63284e6SKumar Kartikeya Dwivedi const char *bpf_diag_reg_type_plain(struct bpf_verifier_env *env, enum bpf_reg_type type);
54daf82487SKumar Kartikeya Dwivedi u64 bpf_diag_event_log_save(struct bpf_verifier_env *env);
55daf82487SKumar Kartikeya Dwivedi void bpf_diag_event_log_restore(struct bpf_verifier_env *env, u64 log_pos);
56956a66e5SKumar Kartikeya Dwivedi u32 bpf_diag_irq_depth(const struct bpf_verifier_state *state);
57b9c5d822SKumar Kartikeya Dwivedi void bpf_diag_free(struct bpf_verifier_env *env);
58d63284e6SKumar Kartikeya Dwivedi void bpf_diag_register_type(struct bpf_verifier_env *env, u32 insn_idx, int regno,
59d63284e6SKumar Kartikeya Dwivedi 			    const char *problem, const char *reason, const char *suggestion);
60d63284e6SKumar Kartikeya Dwivedi void bpf_diag_invalid_deref(struct bpf_verifier_env *env, u32 insn_idx, int regno,
61d63284e6SKumar Kartikeya Dwivedi 			    const char *reg_name, const struct bpf_reg_state *reg,
62d63284e6SKumar Kartikeya Dwivedi 			    enum bpf_diag_invalid_deref_kind kind, s64 offset);
63d63284e6SKumar Kartikeya Dwivedi void bpf_diag_unreadable_reg(struct bpf_verifier_env *env, u32 insn_idx, int regno);
64d63284e6SKumar Kartikeya Dwivedi void bpf_diag_stack_arg_uninit(struct bpf_verifier_env *env, u32 insn_idx, int nargs,
65d63284e6SKumar Kartikeya Dwivedi 			       int stack_arg_slot, const char *callee_name,
66d63284e6SKumar Kartikeya Dwivedi 			       const char *arg_name);
672bdc90f5SKumar Kartikeya Dwivedi void bpf_diag_memory(struct bpf_verifier_env *env, u32 insn_idx, const char *problem,
682bdc90f5SKumar Kartikeya Dwivedi 		     const char *reason, const char *suggestion);
692bdc90f5SKumar Kartikeya Dwivedi void bpf_diag_mem_bounds(struct bpf_verifier_env *env, u32 insn_idx, int regno,
702bdc90f5SKumar Kartikeya Dwivedi 			 const char *reg_name, const char *type_name, const char *proof,
712bdc90f5SKumar Kartikeya Dwivedi 			 int off, int size, u32 mem_size, const struct bpf_reg_state *reg);
725d576462SKumar Kartikeya Dwivedi void bpf_diag_res(struct bpf_verifier_env *env, u32 insn_idx, const char *problem,
735d576462SKumar Kartikeya Dwivedi 		  const char *reason, const char *suggestion);
745d576462SKumar Kartikeya Dwivedi void bpf_diag_lock(struct bpf_verifier_env *env, u32 insn_idx, const char *problem,
755d576462SKumar Kartikeya Dwivedi 		   const char *reason, const char *suggestion,
765d576462SKumar Kartikeya Dwivedi 		   const struct bpf_reference_state *active_lock);
775d576462SKumar Kartikeya Dwivedi void bpf_diag_irq(struct bpf_verifier_env *env, u32 insn_idx, const char *problem,
785d576462SKumar Kartikeya Dwivedi 		  const char *reason, const char *suggestion, u32 depth);
795d576462SKumar Kartikeya Dwivedi void bpf_diag_leak(struct bpf_verifier_env *env, u32 ref_id, u32 alloc_insn, u32 fail_insn);
8066e27273SKumar Kartikeya Dwivedi void bpf_diag_call_type(struct bpf_verifier_env *env, u32 insn_idx, int argno, int regno,
8166e27273SKumar Kartikeya Dwivedi 			int stack_arg_slot, const char *call_name, const char *arg_name,
8266e27273SKumar Kartikeya Dwivedi 			const char *reason, const char *suggestion);
8399a6a288SKumar Kartikeya Dwivedi void bpf_diag_ctx_forbidden(struct bpf_verifier_env *env, u32 insn_idx,
8499a6a288SKumar Kartikeya Dwivedi 			    const char *operation, const char *suggestion);
8599a6a288SKumar Kartikeya Dwivedi void bpf_diag_ctx_active(struct bpf_verifier_env *env, u32 insn_idx, const char *operation,
8699a6a288SKumar Kartikeya Dwivedi 			 enum bpf_diag_context_kind ctx_kind, const char *suggestion);
8799a6a288SKumar Kartikeya Dwivedi void bpf_diag_ctx_required(struct bpf_verifier_env *env, u32 insn_idx, const char *operation,
8899a6a288SKumar Kartikeya Dwivedi 			   enum bpf_diag_context_kind ctx_kind, const char *suggestion);
8999a6a288SKumar Kartikeya Dwivedi void bpf_diag_ctx_underflow(struct bpf_verifier_env *env, u32 insn_idx,
9099a6a288SKumar Kartikeya Dwivedi 			    const char *operation, enum bpf_diag_context_kind ctx_kind,
9199a6a288SKumar Kartikeya Dwivedi 			    const char *suggestion);
92*a8f42783SKumar Kartikeya Dwivedi void bpf_diag_program_structure(struct bpf_verifier_env *env, u32 insn_idx,
93*a8f42783SKumar Kartikeya Dwivedi 				const char *problem, const char *suggestion,
94*a8f42783SKumar Kartikeya Dwivedi 				const char *reason_fmt, ...) __printf(5, 6);
95daf82487SKumar Kartikeya Dwivedi void bpf_diag_record_branch(struct bpf_verifier_env *env, u32 insn_idx, bool cond_true);
96af4ea6e2SKumar Kartikeya Dwivedi void bpf_diag_mod_begin(struct bpf_verifier_env *env, const struct bpf_reg_state *reg,
97af4ea6e2SKumar Kartikeya Dwivedi 			const struct bpf_reg_state *origin, enum bpf_diag_mod_reason reason);
98af4ea6e2SKumar Kartikeya Dwivedi void bpf_diag_mod_end(struct bpf_verifier_env *env);
99af4ea6e2SKumar Kartikeya Dwivedi void bpf_diag_record_scrub(struct bpf_verifier_env *env, const struct bpf_reg_state *reg,
100af4ea6e2SKumar Kartikeya Dwivedi 			   enum bpf_diag_mod_reason reason);
101af4ea6e2SKumar Kartikeya Dwivedi void bpf_diag_record_scrub_stack(struct bpf_verifier_env *env,
102af4ea6e2SKumar Kartikeya Dwivedi 				 const struct bpf_func_state *state, s16 min_off, s16 max_off,
103af4ea6e2SKumar Kartikeya Dwivedi 				 enum bpf_diag_mod_reason reason);
1049ecd7030SKumar Kartikeya Dwivedi void bpf_diag_record_ref_acquire(struct bpf_verifier_env *env, u32 insn_idx, u32 ref_id);
1059ecd7030SKumar Kartikeya Dwivedi void bpf_diag_record_ref_release(struct bpf_verifier_env *env, u32 insn_idx, u32 ref_id);
106956a66e5SKumar Kartikeya Dwivedi void bpf_diag_record_context(struct bpf_verifier_env *env, u32 insn_idx,
107956a66e5SKumar Kartikeya Dwivedi 			     enum bpf_diag_context_kind ctx_kind, bool enter, u32 depth);
1085ad74616SKumar Kartikeya Dwivedi 
1095ad74616SKumar Kartikeya Dwivedi #endif /* __BPF_DIAGNOSTICS_H */
110