Lines Matching refs:env
165 static void diag_print_history(struct bpf_verifier_env *env,
177 struct bpf_verifier_env *env; member
225 bool bpf_diag_enabled(const struct bpf_verifier_env *env) in bpf_diag_enabled() argument
227 return env->log.level & BPF_LOG_LEVEL; in bpf_diag_enabled()
230 static void diag_write(struct bpf_verifier_env *env, const char *fmt, ...) __printf(2, 3);
232 int bpf_diag_init(struct bpf_verifier_env *env) in bpf_diag_init() argument
234 if (!bpf_diag_enabled(env)) in bpf_diag_init()
237 env->diag = kzalloc_obj(struct bpf_diag, GFP_KERNEL_ACCOUNT); in bpf_diag_init()
238 if (!env->diag) in bpf_diag_init()
241 INIT_LIST_HEAD(&env->diag->fmt_chunks); in bpf_diag_init()
245 void bpf_diag_init_frame(struct bpf_verifier_env *env, struct bpf_func_state *state) in bpf_diag_init_frame() argument
247 if (env->diag) in bpf_diag_init_frame()
248 state->diag_frame_id = ++env->diag->frame_id_gen; in bpf_diag_init_frame()
251 static char *diag_fmt_alloc(struct bpf_verifier_env *env, size_t size) in diag_fmt_alloc() argument
253 struct bpf_diag *diag = env->diag; in diag_fmt_alloc()
284 char *bpf_diag_fmt_buf(struct bpf_verifier_env *env, size_t size) in bpf_diag_fmt_buf() argument
288 buf = diag_fmt_alloc(env, size); in bpf_diag_fmt_buf()
294 const char *bpf_diag_vfmt(struct bpf_verifier_env *env, const char *fmt, va_list args) in bpf_diag_vfmt() argument
306 buf = diag_fmt_alloc(env, len + 1); in bpf_diag_vfmt()
312 const char *bpf_diag_fmt(struct bpf_verifier_env *env, const char *fmt, ...) in bpf_diag_fmt() argument
318 buf = bpf_diag_vfmt(env, fmt, args); in bpf_diag_fmt()
323 static struct diag_fmt_mark diag_fmt_save(struct bpf_verifier_env *env) in diag_fmt_save() argument
325 struct bpf_diag *diag = env->diag; in diag_fmt_save()
336 static void diag_fmt_restore(struct bpf_verifier_env *env, struct diag_fmt_mark mark) in diag_fmt_restore() argument
338 struct bpf_diag *diag = env->diag; in diag_fmt_restore()
358 void bpf_diag_free(struct bpf_verifier_env *env) in bpf_diag_free() argument
360 struct bpf_diag *diag = env->diag; in bpf_diag_free()
365 diag_fmt_restore(env, (struct diag_fmt_mark){}); in bpf_diag_free()
368 env->diag = NULL; in bpf_diag_free()
371 static void diag_write(struct bpf_verifier_env *env, const char *fmt, ...) in diag_write() argument
375 if (!bpf_diag_enabled(env)) in diag_write()
379 bpf_verifier_vlog(&env->log, fmt, args); in diag_write()
395 u64 bpf_diag_event_log_save(struct bpf_verifier_env *env) in bpf_diag_event_log_save() argument
397 struct bpf_diag *diag = env->diag; in bpf_diag_event_log_save()
402 void bpf_diag_event_log_restore(struct bpf_verifier_env *env, u64 log_pos) in bpf_diag_event_log_restore() argument
404 struct bpf_diag *diag = env->diag; in bpf_diag_event_log_restore()
444 static void diag_append_history(struct bpf_verifier_env *env, in diag_append_history() argument
448 struct bpf_diag *diag = env->diag; in diag_append_history()
485 static void diag_print_wrapped_prefixed(struct bpf_verifier_env *env, const char *first_prefix, in diag_print_wrapped_prefixed() argument
508 diag_write(env, "%s%.*s\n", prefix, len, line); in diag_print_wrapped_prefixed()
520 const char *bpf_diag_fmt_btf_type(struct bpf_verifier_env *env, const struct btf *btf, u32 type_id) in bpf_diag_fmt_btf_type() argument
522 char *buf = bpf_diag_fmt_buf(env, BPF_DIAG_FMT_BUF_SIZE); in bpf_diag_fmt_btf_type()
542 static void diag_vprint_indented(struct bpf_verifier_env *env, const char *fmt, va_list args)
545 static void diag_vprint_indented(struct bpf_verifier_env *env, const char *fmt, va_list args) in diag_vprint_indented() argument
549 if (!bpf_diag_enabled(env)) in diag_vprint_indented()
554 diag_write(env, "%s<failed to allocate diagnostic text>\n", BPF_DIAG_TEXT_INDENT); in diag_vprint_indented()
558 diag_print_wrapped_prefixed(env, BPF_DIAG_TEXT_INDENT, BPF_DIAG_TEXT_INDENT, buf); in diag_vprint_indented()
605 return bpf_disasm_kfunc_name(ctx->env, insn); in disasm_kfunc_name()
608 static void format_disasm_line(struct bpf_verifier_env *env, int insn_idx, in format_disasm_line() argument
611 struct disasm_ctx ctx = { .env = env }; in format_disasm_line()
623 if (insn_idx < 0 || insn_idx >= env->prog->len) in format_disasm_line()
626 if (insn_idx > 0 && bpf_is_ldimm64(&env->prog->insnsi[insn_idx - 1])) in format_disasm_line()
629 insn = &env->prog->insnsi[insn_idx]; in format_disasm_line()
630 if (bpf_is_ldimm64(insn) && insn_idx + 1 >= env->prog->len) in format_disasm_line()
633 print_bpf_insn(&cbs, insn, env->allow_ptr_leaks); in format_disasm_line()
700 static void bpf_diag_header(struct bpf_verifier_env *env, const char *category, in bpf_diag_header() argument
705 if (!bpf_diag_enabled(env)) in bpf_diag_header()
712 diag_write(env, "\nVerification failed: %s\n", category); in bpf_diag_header()
717 diag_write(env, "\nVerification failed: %s: %c%s\n", category, first, problem + 1); in bpf_diag_header()
720 static void diag_reason(struct bpf_verifier_env *env, const char *fmt, ...) __printf(2, 3);
721 static void diag_suggestion(struct bpf_verifier_env *env, const char *fmt, ...)
724 static void diag_section(struct bpf_verifier_env *env, const char *title) in diag_section() argument
726 if (!bpf_diag_enabled(env)) in diag_section()
729 diag_write(env, "\n%s:\n", title); in diag_section()
732 static void diag_reason(struct bpf_verifier_env *env, const char *fmt, ...) in diag_reason() argument
736 if (!bpf_diag_enabled(env)) in diag_reason()
739 diag_section(env, "Reason"); in diag_reason()
742 diag_vprint_indented(env, fmt, args); in diag_reason()
746 static void diag_suggestion(struct bpf_verifier_env *env, const char *fmt, ...) in diag_suggestion() argument
750 if (!bpf_diag_enabled(env)) in diag_suggestion()
753 diag_section(env, "Suggestion"); in diag_suggestion()
756 diag_vprint_indented(env, fmt, args); in diag_suggestion()
758 diag_write(env, "\n"); in diag_suggestion()
761 static void diag_print_source_annotation(struct bpf_verifier_env *env, int line_width, int indent, in diag_print_source_annotation() argument
767 text = bpf_diag_fmt(env, "%s: %s", label, msg); in diag_print_source_annotation()
768 first_prefix = bpf_diag_fmt(env, " %*s | %*s^-- ", line_width + 4, "", indent, ""); in diag_print_source_annotation()
769 next_prefix = bpf_diag_fmt(env, " %*s | %*s ", line_width + 4, "", indent, ""); in diag_print_source_annotation()
771 diag_print_wrapped_prefixed(env, first_prefix, next_prefix, text); in diag_print_source_annotation()
774 static void diag_print_insn_context(struct bpf_verifier_env *env, u32 insn_idx, in diag_print_insn_context() argument
777 int insn_width = diag_line_width(env->prog->len ? env->prog->len - 1 : 0); in diag_print_insn_context()
783 format_disasm_line(env, insn_idx + row, &disasm_lines[i]); in diag_print_insn_context()
786 diag_write(env, " Instruction context:\n"); in diag_print_insn_context()
791 diag_write(env, " %s%*d | %s\n", in diag_print_insn_context()
797 static void bpf_diag_source(struct bpf_verifier_env *env, u32 insn_idx, const char *label, in bpf_diag_source() argument
807 struct btf *btf = env->prog->aux->btf; in bpf_diag_source()
814 if (!bpf_diag_enabled(env)) in bpf_diag_source()
816 if (!env->diag) in bpf_diag_source()
819 mark = diag_fmt_save(env); in bpf_diag_source()
821 scratch = &env->diag->scratch; in bpf_diag_source()
828 msg = bpf_diag_vfmt(env, fmt, args); in bpf_diag_source()
833 linfo = bpf_find_linfo(env->prog, insn_idx); in bpf_diag_source()
837 diag_write(env, " insn %u\n", insn_idx); in bpf_diag_source()
841 subprog = bpf_find_containing_subprog(env, insn_idx); in bpf_diag_source()
842 subprogno = subprog ? subprog - env->subprog_info : -ENOENT; in bpf_diag_source()
843 func = subprogno >= 0 ? bpf_subprog_name(env, subprogno) : NULL; in bpf_diag_source()
845 diag_write(env, " %s @ %s:%d:%d\n", func, src.file, src.line_num, src.line_col); in bpf_diag_source()
847 diag_write(env, " %s:%d:%d\n", src.file, src.line_num, src.line_col); in bpf_diag_source()
858 linfo = env->prog->aux->linfo; in bpf_diag_source()
860 linfo_end = subprogno >= 0 && subprogno + 1 < env->subprog_cnt ? in bpf_diag_source()
861 env->subprog_info[subprogno + 1].linfo_idx : env->prog->aux->nr_linfo; in bpf_diag_source()
877 diag_write(env, " Source context:\n"); in bpf_diag_source()
878 source_lane = bpf_diag_fmt_buf(env, BPF_DIAG_FMT_BUF_SIZE); in bpf_diag_source()
887 diag_write(env, " %s\n", source_lane); in bpf_diag_source()
889 diag_print_source_annotation(env, width, indent, label, msg); in bpf_diag_source()
891 diag_print_insn_context(env, insn_idx, disasm_lines); in bpf_diag_source()
895 diag_print_source_annotation(env, 0, 0, label, msg); in bpf_diag_source()
896 diag_print_insn_context(env, insn_idx, disasm_lines); in bpf_diag_source()
898 diag_fmt_restore(env, mark); in bpf_diag_source()
901 static const struct bpf_func_state *diag_current_frame(const struct bpf_verifier_env *env) in diag_current_frame() argument
903 return env->cur_state->frame[env->cur_state->curframe]; in diag_current_frame()
906 void bpf_diag_register_type(struct bpf_verifier_env *env, u32 insn_idx, int regno, in bpf_diag_register_type() argument
909 const struct bpf_func_state *frame = diag_current_frame(env); in bpf_diag_register_type()
917 bpf_diag_header(env, REGISTER_TYPE_SAFETY, problem); in bpf_diag_register_type()
918 diag_reason(env, "%s", reason); in bpf_diag_register_type()
920 diag_section(env, "At"); in bpf_diag_register_type()
921 bpf_diag_source(env, insn_idx, "error", "%s", problem); in bpf_diag_register_type()
924 diag_print_history(env, &opts); in bpf_diag_register_type()
926 diag_suggestion(env, "%s", suggestion); in bpf_diag_register_type()
929 const char *bpf_diag_reg_type_plain(struct bpf_verifier_env *env, enum bpf_reg_type type) in bpf_diag_reg_type_plain() argument
959 return reg_type_str(env, type); in bpf_diag_reg_type_plain()
995 void bpf_diag_call_type(struct bpf_verifier_env *env, u32 insn_idx, int argno, int regno, in bpf_diag_call_type() argument
999 const struct bpf_func_state *frame = diag_current_frame(env); in bpf_diag_call_type()
1019 arg_desc = bpf_diag_fmt(env, "%s argument (%s)", ordinal, arg_name); in bpf_diag_call_type()
1021 arg_desc = bpf_diag_fmt(env, "%s argument", ordinal); in bpf_diag_call_type()
1023 arg_desc = bpf_diag_fmt(env, "argument %s", arg_name); in bpf_diag_call_type()
1027 bpf_diag_header(env, CALL_TYPE_SAFETY, "invalid call argument"); in bpf_diag_call_type()
1028 diag_reason(env, "The %s to %s does not satisfy the verifier contract: %s.", in bpf_diag_call_type()
1031 diag_section(env, "At"); in bpf_diag_call_type()
1032 bpf_diag_source(env, insn_idx, "error", "invalid %s for %s", arg_desc, call_name); in bpf_diag_call_type()
1035 diag_print_history(env, &opts); in bpf_diag_call_type()
1037 diag_suggestion(env, "%s", suggestion); in bpf_diag_call_type()
1057 static const char *diag_active_context(struct bpf_verifier_env *env, u32 depth, in diag_active_context() argument
1061 return bpf_diag_fmt(env, "an active %s (depth 1)", context); in diag_active_context()
1062 return bpf_diag_fmt(env, "%u active %ss (depth %u)", depth, context, depth); in diag_active_context()
1065 static u32 diag_context_depth(struct bpf_verifier_env *env, enum bpf_diag_context_kind kind) in diag_context_depth() argument
1069 return env->cur_state->active_rcu_locks; in diag_context_depth()
1071 return env->cur_state->active_preempt_locks; in diag_context_depth()
1073 return bpf_diag_irq_depth(env->cur_state); in diag_context_depth()
1075 return env->cur_state->active_locks; in diag_context_depth()
1082 void bpf_diag_ctx_forbidden(struct bpf_verifier_env *env, u32 insn_idx, in bpf_diag_ctx_forbidden() argument
1090 if (env->cur_state->active_rcu_locks) in bpf_diag_ctx_forbidden()
1092 else if (env->cur_state->active_preempt_locks) in bpf_diag_ctx_forbidden()
1094 else if (env->cur_state->active_irq_id) in bpf_diag_ctx_forbidden()
1096 else if (env->cur_state->active_locks) in bpf_diag_ctx_forbidden()
1101 depth = diag_context_depth(env, ctx_kind); in bpf_diag_ctx_forbidden()
1110 bpf_diag_header(env, EXECUTION_CONTEXT_SAFETY, in bpf_diag_ctx_forbidden()
1115 env, "The operation %s cannot be used in %s because %s. This path is still inside %s.", in bpf_diag_ctx_forbidden()
1116 operation, context, constraint, diag_active_context(env, depth, context)); in bpf_diag_ctx_forbidden()
1118 diag_reason(env, "The operation %s cannot be used in %s because %s.", in bpf_diag_ctx_forbidden()
1122 diag_reason(env, "The operation %s cannot be used in %s.", operation, in bpf_diag_ctx_forbidden()
1126 diag_section(env, "At"); in bpf_diag_ctx_forbidden()
1127 bpf_diag_source(env, insn_idx, "error", "%s is not allowed in %s", operation, in bpf_diag_ctx_forbidden()
1131 diag_print_history(env, &opts); in bpf_diag_ctx_forbidden()
1133 diag_suggestion(env, "%s", suggestion); in bpf_diag_ctx_forbidden()
1136 void bpf_diag_ctx_active(struct bpf_verifier_env *env, u32 insn_idx, const char *operation, in bpf_diag_ctx_active() argument
1139 u32 depth = diag_context_depth(env, ctx_kind); in bpf_diag_ctx_active()
1147 bpf_diag_header(env, EXECUTION_CONTEXT_SAFETY, in bpf_diag_ctx_active()
1150 …env, "The operation %s cannot be used while this path is still inside %s. Leave the region before … in bpf_diag_ctx_active()
1151 operation, diag_active_context(env, depth, context)); in bpf_diag_ctx_active()
1153 diag_section(env, "At"); in bpf_diag_ctx_active()
1154 bpf_diag_source(env, insn_idx, "error", "%s is not allowed before leaving %s", in bpf_diag_ctx_active()
1157 diag_print_history(env, &opts); in bpf_diag_ctx_active()
1159 diag_suggestion(env, "%s", suggestion); in bpf_diag_ctx_active()
1162 void bpf_diag_ctx_required(struct bpf_verifier_env *env, u32 insn_idx, const char *operation, in bpf_diag_ctx_required() argument
1167 bpf_diag_header(env, EXECUTION_CONTEXT_SAFETY, "required context is not active"); in bpf_diag_ctx_required()
1168 diag_reason(env, "The operation %s requires an active %s, but this path is outside one.", in bpf_diag_ctx_required()
1171 diag_section(env, "At"); in bpf_diag_ctx_required()
1172 bpf_diag_source(env, insn_idx, "error", "%s requires %s", operation, context); in bpf_diag_ctx_required()
1174 diag_suggestion(env, "%s", suggestion); in bpf_diag_ctx_required()
1177 void bpf_diag_ctx_underflow(struct bpf_verifier_env *env, u32 insn_idx, in bpf_diag_ctx_underflow() argument
1187 bpf_diag_header(env, EXECUTION_CONTEXT_SAFETY, "unmatched context exit"); in bpf_diag_ctx_underflow()
1189 …env, "The operation %s tries to leave %s, but this path has no active %s to leave. The current dep… in bpf_diag_ctx_underflow()
1192 diag_section(env, "At"); in bpf_diag_ctx_underflow()
1193 bpf_diag_source(env, insn_idx, "error", "%s has no matching enter on this path", in bpf_diag_ctx_underflow()
1196 diag_print_history(env, &opts); in bpf_diag_ctx_underflow()
1198 diag_suggestion(env, "%s", suggestion); in bpf_diag_ctx_underflow()
1201 void bpf_diag_program_structure(struct bpf_verifier_env *env, u32 insn_idx, in bpf_diag_program_structure() argument
1207 bpf_diag_header(env, PROGRAM_STRUCTURE, problem); in bpf_diag_program_structure()
1208 diag_section(env, "Reason"); in bpf_diag_program_structure()
1211 diag_vprint_indented(env, reason_fmt, args); in bpf_diag_program_structure()
1214 diag_section(env, "At"); in bpf_diag_program_structure()
1215 bpf_diag_source(env, insn_idx, "error", "%s", problem); in bpf_diag_program_structure()
1217 diag_suggestion(env, "%s", suggestion); in bpf_diag_program_structure()
1220 void bpf_diag_policy(struct bpf_verifier_env *env, u32 insn_idx, const char *operation, in bpf_diag_policy() argument
1223 bpf_diag_header(env, POLICY, "operation is not allowed"); in bpf_diag_policy()
1224 diag_reason(env, "The %s is not allowed: %s.", operation, reason); in bpf_diag_policy()
1226 diag_section(env, "At"); in bpf_diag_policy()
1227 bpf_diag_source(env, insn_idx, "error", "policy check failed for %s", operation); in bpf_diag_policy()
1229 diag_suggestion(env, "%s", suggestion); in bpf_diag_policy()
1232 void bpf_diag_invalid_deref(struct bpf_verifier_env *env, u32 insn_idx, int regno, in bpf_diag_invalid_deref() argument
1236 const struct bpf_func_state *frame = diag_current_frame(env); in bpf_diag_invalid_deref()
1243 const char *type_name = bpf_diag_reg_type_plain(env, reg->type); in bpf_diag_invalid_deref()
1245 bpf_diag_header(env, REGISTER_TYPE_SAFETY, "invalid dereference"); in bpf_diag_invalid_deref()
1249 diag_reason(env, "%s is an integer scalar here, not a pointer to memory.", in bpf_diag_invalid_deref()
1254 …env, "%s may be NULL here (%s). The program could dereference NULL on this path, so the verifier c… in bpf_diag_invalid_deref()
1259 env, "%s has offset %lld here, but this pointer type must be dereferenced in its original form.", in bpf_diag_invalid_deref()
1265 env, "%s has type %s here, which is not valid for this memory access.", in bpf_diag_invalid_deref()
1270 diag_section(env, "At"); in bpf_diag_invalid_deref()
1272 bpf_diag_source(env, insn_idx, "error", in bpf_diag_invalid_deref()
1275 bpf_diag_source(env, insn_idx, "error", "invalid dereference of %s (%s)", in bpf_diag_invalid_deref()
1279 diag_print_history(env, &opts); in bpf_diag_invalid_deref()
1284 … env, "Add a NULL check before the access and dereference the pointer only on the non-NULL path."); in bpf_diag_invalid_deref()
1288 …env, "Preserve the original pointer in another register, or use only offsets this pointer type per… in bpf_diag_invalid_deref()
1294 …env, "Preserve a pointer-valued register where needed, or reload and revalidate the pointer after … in bpf_diag_invalid_deref()
1299 void bpf_diag_unreadable_reg(struct bpf_verifier_env *env, u32 insn_idx, int regno) in bpf_diag_unreadable_reg() argument
1301 const struct bpf_func_state *frame = diag_current_frame(env); in bpf_diag_unreadable_reg()
1308 const struct bpf_diag_log *log = env->diag ? &env->diag->log : NULL; in bpf_diag_unreadable_reg()
1326 bpf_diag_header(env, REGISTER_TYPE_SAFETY, "unreadable register"); in bpf_diag_unreadable_reg()
1329 …env, "R%d is not readable here. A previous operation invalidated this register, so the verifier ca… in bpf_diag_unreadable_reg()
1332 diag_reason(env, in bpf_diag_unreadable_reg()
1337 …env, "R%d is not readable here. It may never have been initialized, or an earlier operation may ha… in bpf_diag_unreadable_reg()
1340 diag_section(env, "At"); in bpf_diag_unreadable_reg()
1341 bpf_diag_source(env, insn_idx, "error", "R%d is not readable", regno); in bpf_diag_unreadable_reg()
1344 diag_print_history(env, &opts); in bpf_diag_unreadable_reg()
1348 …env, "Avoid using the register after it is invalidated, or initialize it again before this instruc… in bpf_diag_unreadable_reg()
1350 diag_suggestion(env, "Initialize R%d on every path before this instruction.", regno); in bpf_diag_unreadable_reg()
1353 …env, "Initialize the register on every path, or initialize it again after any operation that inval… in bpf_diag_unreadable_reg()
1377 void bpf_diag_stack_arg_uninit(struct bpf_verifier_env *env, u32 insn_idx, int nargs, in bpf_diag_stack_arg_uninit() argument
1381 const struct bpf_func_state *frame = diag_current_frame(env); in bpf_diag_stack_arg_uninit()
1390 arg_buf = bpf_diag_fmt_buf(env, BPF_DIAG_FMT_BUF_SIZE); in bpf_diag_stack_arg_uninit()
1396 bpf_diag_header(env, REGISTER_TYPE_SAFETY, "missing stack argument"); in bpf_diag_stack_arg_uninit()
1399 env, "Function %s expects %d arguments, but %s is not initialized at this call.", in bpf_diag_stack_arg_uninit()
1403 env, "The callee expects %d arguments, but %s is not initialized at this call.", in bpf_diag_stack_arg_uninit()
1406 diag_section(env, "At"); in bpf_diag_stack_arg_uninit()
1407 bpf_diag_source(env, insn_idx, "error", "%s is not initialized", arg_buf); in bpf_diag_stack_arg_uninit()
1410 diag_print_history(env, &opts); in bpf_diag_stack_arg_uninit()
1413 …env, "Write the outgoing stack argument after any operation that may invalidate stored pointer val… in bpf_diag_stack_arg_uninit()
1416 void bpf_diag_memory(struct bpf_verifier_env *env, u32 insn_idx, const char *problem, in bpf_diag_memory() argument
1419 bpf_diag_header(env, MEMORY_SAFETY, problem); in bpf_diag_memory()
1420 diag_reason(env, "%s", reason); in bpf_diag_memory()
1422 diag_section(env, "At"); in bpf_diag_memory()
1423 bpf_diag_source(env, insn_idx, "error", "%s", problem); in bpf_diag_memory()
1425 diag_suggestion(env, "%s", suggestion); in bpf_diag_memory()
1428 void bpf_diag_record_branch(struct bpf_verifier_env *env, u32 insn_idx, bool cond_true) in bpf_diag_record_branch() argument
1438 diag_append_history(env, &event); in bpf_diag_record_branch()
1455 static bool diag_mod_insn_origin(struct bpf_verifier_env *env, u32 insn_idx, in diag_mod_insn_origin() argument
1459 const struct bpf_insn *insn = &env->prog->insnsi[insn_idx]; in diag_mod_insn_origin()
1474 state = env->cur_state->frame[env->cur_state->curframe]; in diag_mod_insn_origin()
1479 static bool diag_mod_keeps_lineage(struct bpf_verifier_env *env, in diag_mod_keeps_lineage() argument
1489 insn = &env->prog->insnsi[event->insn_idx]; in diag_mod_keeps_lineage()
1512 static void diag_record_mod(struct bpf_verifier_env *env, u32 insn_idx, in diag_record_mod() argument
1535 } else if (diag_mod_insn_origin(env, insn_idx, &target, &event.mod.origin)) { in diag_record_mod()
1542 diag_mod_keeps_lineage(env, &event)) in diag_record_mod()
1545 diag_append_history(env, &event); in diag_record_mod()
1548 static struct bpf_reg_state *target_to_reg(struct bpf_verifier_env *env, in target_to_reg() argument
1551 struct bpf_verifier_state *vstate = env->cur_state; in target_to_reg()
1579 static bool reg_to_target(struct bpf_verifier_env *env, const struct bpf_reg_state *reg, in reg_to_target() argument
1582 struct bpf_verifier_state *vstate = env->cur_state; in reg_to_target()
1620 void bpf_diag_mod_begin(struct bpf_verifier_env *env, const struct bpf_reg_state *reg, in bpf_diag_mod_begin() argument
1623 struct bpf_diag *diag = env->diag; in bpf_diag_mod_begin()
1627 diag->mod.active = reg_to_target(env, reg, &diag->mod.target); in bpf_diag_mod_begin()
1631 diag->mod.insn_idx = env->insn_idx; in bpf_diag_mod_begin()
1633 diag->mod.origin_valid = origin && reg_to_target(env, origin, &diag->mod.origin); in bpf_diag_mod_begin()
1636 void bpf_diag_mod_end(struct bpf_verifier_env *env) in bpf_diag_mod_end() argument
1638 struct bpf_diag *diag = env->diag; in bpf_diag_mod_end()
1648 new_reg = target_to_reg(env, &diag->mod.target); in bpf_diag_mod_end()
1651 diag_record_mod(env, diag->mod.insn_idx, diag->mod.target, diag->mod.reason, in bpf_diag_mod_end()
1656 void bpf_diag_record_scrub(struct bpf_verifier_env *env, const struct bpf_reg_state *reg, in bpf_diag_record_scrub() argument
1661 if (!env->diag || reg->type == NOT_INIT || !reg_to_target(env, reg, &target)) in bpf_diag_record_scrub()
1663 diag_record_mod(env, env->insn_idx, target, reason, reg, NULL, NULL); in bpf_diag_record_scrub()
1666 void bpf_diag_record_scrub_stack(struct bpf_verifier_env *env, in bpf_diag_record_scrub_stack() argument
1670 diag_record_mod(env, env->insn_idx, in bpf_diag_record_scrub_stack()
1675 static void diag_record_ref(struct bpf_verifier_env *env, u32 insn_idx, u8 kind, u32 ref_id) in diag_record_ref() argument
1685 diag_append_history(env, &event); in diag_record_ref()
1688 void bpf_diag_record_ref_acquire(struct bpf_verifier_env *env, u32 insn_idx, u32 ref_id) in bpf_diag_record_ref_acquire() argument
1690 diag_record_ref(env, insn_idx, BPF_DIAG_HISTORY_REF_ACQUIRE, ref_id); in bpf_diag_record_ref_acquire()
1693 void bpf_diag_record_ref_release(struct bpf_verifier_env *env, u32 insn_idx, u32 ref_id) in bpf_diag_record_ref_release() argument
1695 diag_record_ref(env, insn_idx, BPF_DIAG_HISTORY_REF_RELEASE, ref_id); in bpf_diag_record_ref_release()
1698 void bpf_diag_record_context(struct bpf_verifier_env *env, u32 insn_idx, in bpf_diag_record_context() argument
1715 diag_append_history(env, &event); in bpf_diag_record_context()
1780 static void diag_build_lineage(struct bpf_verifier_env *env, struct bpf_diag_log *log, in diag_build_lineage() argument
1822 if (diag_mod_keeps_lineage(env, event)) in diag_build_lineage()
1891 static const char *diag_s64_str(struct bpf_verifier_env *env, s64 value) in diag_s64_str() argument
1893 return diag_s64_bound_name(value) ?: bpf_diag_fmt(env, "%lld", value); in diag_s64_str()
1896 static const char *diag_u64_str(struct bpf_verifier_env *env, u64 value) in diag_u64_str() argument
1898 return diag_u64_bound_name(value) ?: bpf_diag_fmt(env, "%llu", value); in diag_u64_str()
1912 static const char *diag_scalar_range(struct bpf_verifier_env *env, struct cnum64 range) in diag_scalar_range() argument
1914 return bpf_diag_fmt(env, "signed range [%s, %s], unsigned range [%s, %s]", in diag_scalar_range()
1915 diag_s64_str(env, cnum64_smin(range)), in diag_scalar_range()
1916 diag_s64_str(env, cnum64_smax(range)), in diag_scalar_range()
1917 diag_u64_str(env, cnum64_umin(range)), in diag_scalar_range()
1918 diag_u64_str(env, cnum64_umax(range))); in diag_scalar_range()
1921 const char *bpf_diag_fmt_s64_sum(struct bpf_verifier_env *env, s64 value, int addend) in bpf_diag_fmt_s64_sum() argument
1926 return bpf_diag_fmt(env, "%lld plus %d (%s)", value, addend, in bpf_diag_fmt_s64_sum()
1929 return bpf_diag_fmt(env, "%lld", sum); in bpf_diag_fmt_s64_sum()
1932 static const char *diag_access_offset(struct bpf_verifier_env *env, int off, in diag_access_offset() argument
1936 return bpf_diag_fmt(env, "constant %s", in diag_access_offset()
1937 bpf_diag_fmt_s64_sum(env, (s64)reg->var_off.value, off)); in diag_access_offset()
1940 return bpf_diag_fmt(env, "unbounded"); in diag_access_offset()
1943 return bpf_diag_fmt(env, in diag_access_offset()
1946 diag_scalar_range(env, reg->r64)); in diag_access_offset()
1947 return bpf_diag_fmt(env, "variable: known bits %#llx, unknown mask %#llx; %s", in diag_access_offset()
1949 diag_scalar_range(env, reg->r64)); in diag_access_offset()
1952 void bpf_diag_mem_bounds(struct bpf_verifier_env *env, u32 insn_idx, int regno, in bpf_diag_mem_bounds() argument
1956 const struct bpf_func_state *frame = diag_current_frame(env); in bpf_diag_mem_bounds()
1965 if (!bpf_diag_enabled(env)) in bpf_diag_mem_bounds()
1968 offset_desc = diag_access_offset(env, off, reg); in bpf_diag_mem_bounds()
1970 bpf_diag_header(env, MEMORY_SAFETY, "access outside bounds"); in bpf_diag_mem_bounds()
1972 …env, "The verifier cannot prove offset + access_size <= object_size. Here, %s. %s is %s; offset is… in bpf_diag_mem_bounds()
1975 diag_section(env, "At"); in bpf_diag_mem_bounds()
1976 bpf_diag_source(env, insn_idx, "error", "access may be outside object bounds"); in bpf_diag_mem_bounds()
1979 diag_print_history(env, &opts); in bpf_diag_mem_bounds()
1982 env, "Add or adjust a bounds check that proves offset + access_size stays within the object."); in bpf_diag_mem_bounds()
1999 static void diag_res_report(struct bpf_verifier_env *env, u32 insn_idx, const char *problem, in diag_res_report() argument
2002 bpf_diag_header(env, RESOURCE_LIFETIME_SAFETY, problem); in diag_res_report()
2003 diag_reason(env, "%s", reason); in diag_res_report()
2005 diag_section(env, "At"); in diag_res_report()
2006 bpf_diag_source(env, insn_idx, "error", "%s", problem); in diag_res_report()
2009 void bpf_diag_res(struct bpf_verifier_env *env, u32 insn_idx, const char *problem, in bpf_diag_res() argument
2012 diag_res_report(env, insn_idx, problem, reason); in bpf_diag_res()
2013 diag_suggestion(env, "%s", suggestion); in bpf_diag_res()
2016 void bpf_diag_lock(struct bpf_verifier_env *env, u32 insn_idx, const char *problem, in bpf_diag_lock() argument
2020 diag_res_report(env, insn_idx, problem, reason); in bpf_diag_lock()
2023 diag_section(env, "Active lock"); in bpf_diag_lock()
2024 bpf_diag_source(env, active_lock->insn_idx, "acquired", in bpf_diag_lock()
2029 diag_suggestion(env, "%s", suggestion); in bpf_diag_lock()
2032 void bpf_diag_irq(struct bpf_verifier_env *env, u32 insn_idx, const char *problem, in bpf_diag_irq() argument
2041 bpf_diag_header(env, RESOURCE_LIFETIME_SAFETY, problem); in bpf_diag_irq()
2042 diag_reason(env, "%s", reason); in bpf_diag_irq()
2044 diag_section(env, "At"); in bpf_diag_irq()
2045 bpf_diag_source(env, insn_idx, "error", "%s", problem); in bpf_diag_irq()
2048 diag_print_history(env, &opts); in bpf_diag_irq()
2050 diag_suggestion(env, "%s", suggestion); in bpf_diag_irq()
2053 void bpf_diag_leak(struct bpf_verifier_env *env, u32 ref_id, u32 alloc_insn, u32 fail_insn) in bpf_diag_leak() argument
2060 bpf_diag_header(env, RESOURCE_LIFETIME_SAFETY, "unreleased resource"); in bpf_diag_leak()
2062 …env, "Owned resource (id=%u) was acquired at instruction %u and still needs to be released before … in bpf_diag_leak()
2065 diag_section(env, "At"); in bpf_diag_leak()
2066 bpf_diag_source(env, fail_insn, "error", in bpf_diag_leak()
2069 diag_print_history(env, &opts); in bpf_diag_leak()
2072 …env, "Release or transfer ownership of the acquired resource on every path before the program exit… in bpf_diag_leak()
2075 static const char *diag_var_offset(struct bpf_verifier_env *env, in diag_var_offset() argument
2079 return bpf_diag_fmt(env, "at offset %lld", (s64)snapshot->var_off.value); in diag_var_offset()
2082 return bpf_diag_fmt(env, "with unknown offset"); in diag_var_offset()
2084 return bpf_diag_fmt(env, in diag_var_offset()
2087 diag_scalar_range(env, snapshot->r64)); in diag_var_offset()
2098 static const char *diag_reg_snapshot(struct bpf_verifier_env *env, in diag_reg_snapshot() argument
2101 const char *type_name = reg_type_str(env, snapshot->type); in diag_reg_snapshot()
2102 const char *offset = diag_var_offset(env, snapshot); in diag_reg_snapshot()
2104 bpf_diag_fmt_btf_type(env, snapshot->btf, snapshot->btf_id) : NULL; in diag_reg_snapshot()
2109 return bpf_diag_fmt(env, "integer scalar value %lld", in diag_reg_snapshot()
2112 return bpf_diag_fmt(env, "integer scalar with unknown value"); in diag_reg_snapshot()
2114 return bpf_diag_fmt(env, "integer scalar value %lld", in diag_reg_snapshot()
2116 return bpf_diag_fmt(env, "integer scalar with %s", in diag_reg_snapshot()
2117 diag_scalar_range(env, snapshot->r64)); in diag_reg_snapshot()
2121 return bpf_diag_fmt(env, "uninitialized value"); in diag_reg_snapshot()
2124 return bpf_diag_fmt(env, "context pointer %s", offset); in diag_reg_snapshot()
2127 return bpf_diag_fmt(env, "stack pointer %s", offset); in diag_reg_snapshot()
2135 return bpf_diag_fmt(env, "%s from %s %s", kind, map_name, offset); in diag_reg_snapshot()
2136 return bpf_diag_fmt(env, "%s %s", kind, offset); in diag_reg_snapshot()
2142 return bpf_diag_fmt(env, "map pointer for map %s", map_name); in diag_reg_snapshot()
2143 return bpf_diag_fmt(env, "map pointer"); in diag_reg_snapshot()
2148 return bpf_diag_fmt(env, "borrowed allocated object pointer type=%s", btf); in diag_reg_snapshot()
2149 return bpf_diag_fmt(env, "borrowed allocated object pointer"); in diag_reg_snapshot()
2154 return bpf_diag_fmt(env, "owned allocated object pointer type=%s", btf); in diag_reg_snapshot()
2155 return bpf_diag_fmt(env, "owned allocated object pointer"); in diag_reg_snapshot()
2159 return bpf_diag_fmt(env, "%s type=%s %s", type_name, btf, offset); in diag_reg_snapshot()
2161 return bpf_diag_fmt(env, "%s %s", type_name, offset); in diag_reg_snapshot()
2164 static const char *diag_mod_target_desc(struct bpf_verifier_env *env, in diag_mod_target_desc() argument
2169 return bpf_diag_fmt(env, "R%u", target->regno); in diag_mod_target_desc()
2171 return bpf_diag_fmt(env, "*(R11-%u)", (target->stack_arg + 1) * BPF_REG_SIZE); in diag_mod_target_desc()
2173 return bpf_diag_fmt(env, "stack slot fp%d", -(target->spi + 1) * BPF_REG_SIZE); in diag_mod_target_desc()
2179 static void diag_print_mod(struct bpf_verifier_env *env, const struct bpf_diag_history_event *event) in diag_print_mod() argument
2187 env, event->insn_idx, "invalidated", in diag_print_mod()
2193 old = diag_reg_snapshot(env, &event->mod.old); in diag_print_mod()
2194 new = diag_reg_snapshot(env, &event->mod.new); in diag_print_mod()
2195 target_desc = diag_mod_target_desc(env, target); in diag_print_mod()
2228 bpf_diag_source(env, event->insn_idx, "invalidated", in diag_print_mod()
2233 bpf_diag_source(env, event->insn_idx, label, "%s changed from %s to %s", target_desc, in diag_print_mod()
2237 static void diag_print_ref_event(struct bpf_verifier_env *env, in diag_print_ref_event() argument
2243 bpf_diag_source(env, event->insn_idx, label, "owned resource (id=%u)", in diag_print_ref_event()
2264 static void diag_print_context_event(struct bpf_verifier_env *env, in diag_print_context_event() argument
2267 bpf_diag_source(env, event->insn_idx, "context", "%s %s; depth is now %u", in diag_print_context_event()
2272 static void diag_print_history(struct bpf_verifier_env *env, in diag_print_history() argument
2285 if (!bpf_diag_enabled(env)) in diag_print_history()
2288 if (!env->diag) in diag_print_history()
2290 log = &env->diag->log; in diag_print_history()
2292 diag_build_lineage(env, log, &filter); in diag_print_history()
2304 diag_section(env, "Causal path"); in diag_print_history()
2305 mark = diag_fmt_save(env); in diag_print_history()
2311 diag_fmt_restore(env, mark); in diag_print_history()
2318 diag_write(env, "\n"); in diag_print_history()
2320 diag_write(env, " %u intermediate causal-history events omitted\n", in diag_print_history()
2327 diag_write(env, "\n"); in diag_print_history()
2332 bpf_diag_source(env, event->insn_idx, "branch", in diag_print_history()
2338 diag_print_mod(env, event); in diag_print_history()
2342 diag_print_ref_event(env, event); in diag_print_history()
2345 diag_print_context_event(env, event); in diag_print_history()
2353 diag_write(env, " no retained diagnostic events on this path\n"); in diag_print_history()
2355 diag_write(env, " %llu older causal-history event%s not retained because diagnostic " in diag_print_history()
2358 diag_fmt_restore(env, mark); in diag_print_history()