Augment selected existing internal-error paths with Verifier Internal Error reports. These reports avoid suggesting source-level fixes and instead identify the verifier invariant that failed. Cover non-overwritten BPF_PTR_POISON helper argument types and inconsistent kfunc graph-node argument classification. Signed-off-by: Kumar Kartikeya Dwivedi --- kernel/bpf/diagnostics.c | 16 ++++++++++++++++ kernel/bpf/diagnostics.h | 3 +++ kernel/bpf/verifier.c | 12 +++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/diagnostics.c b/kernel/bpf/diagnostics.c index 18217f5f709a..d27bd314d194 100644 --- a/kernel/bpf/diagnostics.c +++ b/kernel/bpf/diagnostics.c @@ -1195,6 +1195,22 @@ void bpf_diag_report_limit(struct bpf_verifier_env *env, u32 insn_idx, bpf_diag_report_suggestion(env, "%s", suggestion); } +void bpf_diag_report_internal_error(struct bpf_verifier_env *env, + u32 insn_idx, const char *problem, + const char *reason) +{ + bpf_diag_report_header(env, BPF_DIAG_CATEGORY_VERIFIER_INTERNAL_ERROR, + problem); + bpf_diag_report_reason(env, "The verifier hit an internal error: %s", + reason); + + bpf_diag_report_section(env, "At"); + bpf_diag_report_source(env, insn_idx, "error", "%s", problem); + + bpf_diag_report_suggestion(env, + "Report this problem to bpf@vger.kernel.org with the full verifier log and program."); +} + void bpf_diag_report_invalid_deref(struct bpf_verifier_env *env, u32 insn_idx, int regno, const char *reg_name, const char *type_name, diff --git a/kernel/bpf/diagnostics.h b/kernel/bpf/diagnostics.h index 559c0169062c..97cdaad7b606 100644 --- a/kernel/bpf/diagnostics.h +++ b/kernel/bpf/diagnostics.h @@ -228,6 +228,9 @@ void bpf_diag_report_limit(struct bpf_verifier_env *env, u32 insn_idx, const char *limit, const char *suggestion, const char *reason_fmt, ...) __printf(5, 6); +void bpf_diag_report_internal_error(struct bpf_verifier_env *env, + u32 insn_idx, const char *problem, + const char *reason); void bpf_diag_record_branch(struct bpf_verifier_env *env, u32 insn_idx, bool cond_true); void bpf_diag_record_reg_mod(struct bpf_verifier_env *env, u32 insn_idx, diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ec51e0c81053..5c60fe033271 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8481,6 +8481,9 @@ static int check_reg_type(struct bpf_verifier_env *env, struct bpf_reg_state *re verbose(env, "verifier internal error:"); verbose(env, "%s has non-overwritten BPF_PTR_POISON type\n", reg_arg_name(env, argno)); + bpf_diag_report_internal_error(env, env->insn_idx, + "poisoned helper argument type", + "helper type checking reached a non-overwritten BPF_PTR_POISON expected type."); return -EACCES; } @@ -12560,12 +12563,19 @@ static bool check_kfunc_is_graph_node_api(struct bpf_verifier_env *env, default: verbose(env, "verifier internal error: unexpected graph node argument type %s\n", btf_field_type_name(node_field_type)); + bpf_diag_report_internal_error(env, env->insn_idx, + "unexpected graph node argument type", + "the kfunc graph-node checker saw an unsupported graph node field type."); return false; } - if (!ret) + if (!ret) { verbose(env, "verifier internal error: %s node arg for unknown kfunc\n", btf_field_type_name(node_field_type)); + bpf_diag_report_internal_error(env, env->insn_idx, + "graph node argument for unknown kfunc", + "the kfunc graph-node checker could not map this graph node argument to the called kfunc."); + } return ret; } -- 2.53.0