xref: /linux/kernel/bpf/diagnostics.c (revision 09a0c2d678643aa8362ed83ea21b3a21566b318a)
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (c) 2026 Meta Platforms, Inc. and affiliates.
3 
4 #include <linux/bpf.h>
5 #include <linux/bpf_verifier.h>
6 #include <linux/btf.h>
7 #include <linux/ctype.h>
8 #include <linux/kernel.h>
9 #include <linux/list.h>
10 #include <linux/seq_buf.h>
11 #include <linux/overflow.h>
12 #include <linux/slab.h>
13 #include <linux/stdarg.h>
14 #include <linux/string.h>
15 
16 #include "disasm.h"
17 #include "diagnostics.h"
18 
19 #define REGISTER_TYPE_SAFETY "Register Type Safety"
20 #define MEMORY_SAFETY "Memory Safety"
21 #define RESOURCE_LIFETIME_SAFETY "Resource Lifetime Safety"
22 #define CALL_TYPE_SAFETY "Call Type Safety"
23 #define EXECUTION_CONTEXT_SAFETY "Execution Context Safety"
24 #define PROGRAM_STRUCTURE "Program Structure"
25 #define POLICY "Policy"
26 
27 #define BPF_DIAG_TEXT_WIDTH 100
28 #define BPF_DIAG_TEXT_INDENT "  "
29 #define BPF_DIAG_CONTEXT 2
30 #define BPF_DIAG_CONTEXT_CNT (1 + BPF_DIAG_CONTEXT * 2)
31 #define BPF_DIAG_HISTORY_RENDER_MAX 64
32 #define BPF_DIAG_SOURCE_LANE_WIDTH 88
33 #define BPF_DIAG_TAB_WIDTH 8
34 #define BPF_DIAG_FMT_CHUNK_SIZE (PAGE_SIZE - sizeof(struct diag_fmt_chunk))
35 #define BPF_DIAG_FMT_BUF_SIZE 256
36 #define BPF_DIAG_EVENT_LOG_MAX_SIZE (64U << 20)
37 #define DISASM_LINE_LEN 160
38 
39 enum bpf_diag_mod_target_kind {
40 	BPF_DIAG_MOD_TARGET_NONE,
41 	BPF_DIAG_MOD_TARGET_REG,
42 	BPF_DIAG_MOD_TARGET_STACK_ARG,
43 	BPF_DIAG_MOD_TARGET_STACK_SLOT,
44 	BPF_DIAG_MOD_TARGET_STACK_RANGE,
45 };
46 
47 struct bpf_diag_mod_target {
48 	u32 frame_id;
49 	union {
50 		struct {
51 			s16 min_off;
52 			s16 max_off;
53 		} range;
54 		u16 spi;
55 		u8 regno;
56 		u8 stack_arg;
57 	};
58 	u8 frameno;
59 	u8 kind;
60 };
61 
62 static struct bpf_diag_mod_target diag_reg_target(u32 frame_id, u8 frameno, u8 regno)
63 {
64 	return (struct bpf_diag_mod_target){
65 		.frame_id = frame_id,
66 		.frameno = frameno,
67 		.kind = BPF_DIAG_MOD_TARGET_REG,
68 		.regno = regno,
69 	};
70 }
71 
72 static struct bpf_diag_mod_target diag_stack_arg_target(u32 frame_id, u8 frameno, u8 slot)
73 {
74 	return (struct bpf_diag_mod_target){
75 		.frame_id = frame_id,
76 		.frameno = frameno,
77 		.kind = BPF_DIAG_MOD_TARGET_STACK_ARG,
78 		.stack_arg = slot,
79 	};
80 }
81 
82 static struct bpf_diag_mod_target diag_stack_slot_target(u32 frame_id, u8 frameno, u16 spi)
83 {
84 	return (struct bpf_diag_mod_target){
85 		.frame_id = frame_id,
86 		.frameno = frameno,
87 		.kind = BPF_DIAG_MOD_TARGET_STACK_SLOT,
88 		.spi = spi,
89 	};
90 }
91 
92 static struct bpf_diag_mod_target diag_stack_range_target(u32 frame_id, u8 frameno,
93 							  s16 min_off, s16 max_off)
94 {
95 	return (struct bpf_diag_mod_target){
96 		.frame_id = frame_id,
97 		.frameno = frameno,
98 		.kind = BPF_DIAG_MOD_TARGET_STACK_RANGE,
99 		.range.min_off = min_off,
100 		.range.max_off = max_off,
101 	};
102 }
103 
104 struct bpf_diag_reg_snapshot {
105 	u32 type;
106 	u32 btf_id;
107 	const struct bpf_map *map_ptr;
108 	const struct btf *btf;
109 	struct tnum var_off;
110 	struct cnum64 r64;
111 };
112 
113 enum bpf_diag_history_kind {
114 	BPF_DIAG_HISTORY_BRANCH,
115 	BPF_DIAG_HISTORY_MOD,
116 	BPF_DIAG_HISTORY_REF_ACQUIRE,
117 	BPF_DIAG_HISTORY_REF_RELEASE,
118 	BPF_DIAG_HISTORY_CONTEXT,
119 };
120 
121 struct bpf_diag_history_event {
122 	u32 insn_idx : 24;
123 	u32 kind : 8;
124 	u8 in_lineage : 1;
125 	union {
126 		struct {
127 			bool cond_true;
128 		} branch;
129 		struct {
130 			struct bpf_diag_mod_target target;
131 			struct bpf_diag_mod_target origin;
132 			struct bpf_diag_reg_snapshot old, new;
133 			u8 reason;
134 			bool origin_valid;
135 		} mod;
136 		struct {
137 			u32 ref_id;
138 		} ref;
139 		struct {
140 			u32 depth;
141 			u8 kind;
142 			bool enter;
143 		} ctx;
144 	};
145 };
146 
147 enum bpf_diag_history_scope {
148 	BPF_DIAG_HISTORY_SCOPE_REG,
149 	BPF_DIAG_HISTORY_SCOPE_STACK_ARG,
150 	BPF_DIAG_HISTORY_SCOPE_REF,
151 	BPF_DIAG_HISTORY_SCOPE_CONTEXT,
152 };
153 
154 struct bpf_diag_history_opts {
155 	enum bpf_diag_history_scope scope;
156 	u32 frame_id;
157 	u32 frameno;
158 	int regno;
159 	int stack_arg_slot;
160 	u32 ref_id;
161 	enum bpf_diag_context_kind ctx_kind;
162 	u32 ctx_depth;
163 };
164 
165 static void diag_print_history(struct bpf_verifier_env *env,
166 			       const struct bpf_diag_history_opts *opts);
167 static bool diag_target_matches(const struct bpf_diag_mod_target *event_target,
168 				const struct bpf_diag_mod_target *target);
169 static const char *diag_context_name(enum bpf_diag_context_kind kind);
170 struct disasm_line {
171 	char text[DISASM_LINE_LEN];
172 	int idx;
173 	bool valid;
174 };
175 
176 struct disasm_ctx {
177 	struct bpf_verifier_env *env;
178 	struct seq_buf seq;
179 };
180 
181 struct diag_fmt_chunk {
182 	struct list_head node;
183 	struct seq_buf seq;
184 	char data[];
185 };
186 
187 struct diag_fmt_mark {
188 	struct diag_fmt_chunk *chunk;
189 	size_t len;
190 };
191 
192 struct bpf_diag_log {
193 	struct bpf_diag_history_event *events;
194 	/* Sequence number of the oldest retained event on the active path. */
195 	u64 first_seq;
196 	u32 cnt;
197 	u32 cap;
198 	u32 head;
199 	bool growth_failed;
200 };
201 
202 struct bpf_diag_scratch {
203 	struct bpf_linfo_source source_lines[BPF_DIAG_CONTEXT_CNT];
204 	struct disasm_line disasm_lines[BPF_DIAG_CONTEXT_CNT];
205 };
206 
207 struct bpf_diag_mod_scope {
208 	struct bpf_reg_state target_reg_snapshot;
209 	struct bpf_diag_mod_target target;
210 	struct bpf_diag_mod_target origin;
211 	enum bpf_diag_mod_reason reason;
212 	u32 insn_idx;
213 	bool active;
214 	bool origin_valid;
215 };
216 
217 struct bpf_diag {
218 	struct bpf_diag_log log;
219 	struct bpf_diag_scratch scratch;
220 	struct list_head fmt_chunks;
221 	struct bpf_diag_mod_scope mod;
222 	u32 frame_id_gen;
223 };
224 
225 bool bpf_diag_enabled(const struct bpf_verifier_env *env)
226 {
227 	return env->log.level & BPF_LOG_LEVEL;
228 }
229 
230 static void diag_write(struct bpf_verifier_env *env, const char *fmt, ...) __printf(2, 3);
231 
232 int bpf_diag_init(struct bpf_verifier_env *env)
233 {
234 	if (!bpf_diag_enabled(env))
235 		return 0;
236 
237 	env->diag = kzalloc_obj(struct bpf_diag, GFP_KERNEL_ACCOUNT);
238 	if (!env->diag)
239 		return -ENOMEM;
240 
241 	INIT_LIST_HEAD(&env->diag->fmt_chunks);
242 	return 0;
243 }
244 
245 void bpf_diag_init_frame(struct bpf_verifier_env *env, struct bpf_func_state *state)
246 {
247 	if (env->diag)
248 		state->diag_frame_id = ++env->diag->frame_id_gen;
249 }
250 
251 static char *diag_fmt_alloc(struct bpf_verifier_env *env, size_t size)
252 {
253 	struct bpf_diag *diag = env->diag;
254 	struct diag_fmt_chunk *chunk;
255 	size_t capacity, available;
256 	char *buf;
257 
258 	if (!diag || !size || size > INT_MAX)
259 		return NULL;
260 
261 	if (!list_empty(&diag->fmt_chunks)) {
262 		chunk = list_last_entry(&diag->fmt_chunks, struct diag_fmt_chunk, node);
263 		available = seq_buf_get_buf(&chunk->seq, &buf);
264 		if (available >= size)
265 			goto commit;
266 	}
267 
268 	capacity = max_t(size_t, BPF_DIAG_FMT_CHUNK_SIZE, size);
269 	chunk = kmalloc(struct_size(chunk, data, capacity), GFP_KERNEL_ACCOUNT);
270 	if (!chunk)
271 		return NULL;
272 
273 	seq_buf_init(&chunk->seq, chunk->data, capacity);
274 	list_add_tail(&chunk->node, &diag->fmt_chunks);
275 	available = seq_buf_get_buf(&chunk->seq, &buf);
276 	if (WARN_ON_ONCE(available < size))
277 		return NULL;
278 
279 commit:
280 	seq_buf_commit(&chunk->seq, size);
281 	return buf;
282 }
283 
284 char *bpf_diag_fmt_buf(struct bpf_verifier_env *env, size_t size)
285 {
286 	char *buf;
287 
288 	buf = diag_fmt_alloc(env, size);
289 	if (buf)
290 		buf[0] = '\0';
291 	return buf;
292 }
293 
294 const char *bpf_diag_vfmt(struct bpf_verifier_env *env, const char *fmt, va_list args)
295 {
296 	va_list copy;
297 	char *buf;
298 	int len;
299 
300 	va_copy(copy, args);
301 	len = vsnprintf(NULL, 0, fmt, copy);
302 	va_end(copy);
303 	if (len < 0 || len == INT_MAX)
304 		return "";
305 
306 	buf = diag_fmt_alloc(env, len + 1);
307 	if (buf)
308 		vsnprintf(buf, len + 1, fmt, args);
309 	return buf ?: "";
310 }
311 
312 const char *bpf_diag_fmt(struct bpf_verifier_env *env, const char *fmt, ...)
313 {
314 	const char *buf;
315 	va_list args;
316 
317 	va_start(args, fmt);
318 	buf = bpf_diag_vfmt(env, fmt, args);
319 	va_end(args);
320 	return buf;
321 }
322 
323 static struct diag_fmt_mark diag_fmt_save(struct bpf_verifier_env *env)
324 {
325 	struct bpf_diag *diag = env->diag;
326 	struct diag_fmt_mark mark = {};
327 
328 	if (!diag || list_empty(&diag->fmt_chunks))
329 		return mark;
330 
331 	mark.chunk = list_last_entry(&diag->fmt_chunks, struct diag_fmt_chunk, node);
332 	mark.len = mark.chunk->seq.len;
333 	return mark;
334 }
335 
336 static void diag_fmt_restore(struct bpf_verifier_env *env, struct diag_fmt_mark mark)
337 {
338 	struct bpf_diag *diag = env->diag;
339 	struct diag_fmt_chunk *chunk;
340 
341 	if (!diag)
342 		return;
343 
344 	while (!list_empty(&diag->fmt_chunks)) {
345 		chunk = list_last_entry(&diag->fmt_chunks, struct diag_fmt_chunk, node);
346 		if (chunk == mark.chunk)
347 			break;
348 		list_del(&chunk->node);
349 		kfree(chunk);
350 	}
351 
352 	if (mark.chunk) {
353 		mark.chunk->seq.len = mark.len;
354 		seq_buf_str(&mark.chunk->seq);
355 	}
356 }
357 
358 void bpf_diag_free(struct bpf_verifier_env *env)
359 {
360 	struct bpf_diag *diag = env->diag;
361 
362 	if (!diag)
363 		return;
364 
365 	diag_fmt_restore(env, (struct diag_fmt_mark){});
366 	kvfree(diag->log.events);
367 	kfree(diag);
368 	env->diag = NULL;
369 }
370 
371 static void diag_write(struct bpf_verifier_env *env, const char *fmt, ...)
372 {
373 	va_list args;
374 
375 	if (!bpf_diag_enabled(env))
376 		return;
377 
378 	va_start(args, fmt);
379 	bpf_verifier_vlog(&env->log, fmt, args);
380 	va_end(args);
381 }
382 
383 static u64 log_end(const struct bpf_diag_log *log)
384 {
385 	return log->first_seq + log->cnt;
386 }
387 
388 static u32 log_pos(const struct bpf_diag_log *log, u32 idx)
389 {
390 	u32 pos = log->head + idx;
391 
392 	return pos < log->cap ? pos : pos - log->cap;
393 }
394 
395 u64 bpf_diag_event_log_save(struct bpf_verifier_env *env)
396 {
397 	struct bpf_diag *diag = env->diag;
398 
399 	return diag ? log_end(&diag->log) : 0;
400 }
401 
402 void bpf_diag_event_log_restore(struct bpf_verifier_env *env, u64 log_pos)
403 {
404 	struct bpf_diag *diag = env->diag;
405 	struct bpf_diag_log *log;
406 	u64 end_seq;
407 
408 	if (!diag)
409 		return;
410 
411 	log = &diag->log;
412 	end_seq = log_end(log);
413 	if (WARN_ON_ONCE(log_pos > end_seq))
414 		log_pos = end_seq;
415 
416 	/*
417 	 * A deep abandoned path may have rotated away the shared prefix. In
418 	 * that case, restart with an empty retained suffix and remember that
419 	 * every event before the restored mark is unavailable.
420 	 */
421 	if (log_pos <= log->first_seq) {
422 		log->first_seq = log_pos;
423 		log->head = 0;
424 		log->cnt = 0;
425 		return;
426 	}
427 
428 	log->cnt = log_pos - log->first_seq;
429 }
430 
431 u32 bpf_diag_irq_depth(const struct bpf_verifier_state *state)
432 {
433 	u32 depth = 0;
434 	int i;
435 
436 	for (i = 0; i < state->acquired_refs; i++) {
437 		if (state->refs[i].type == REF_TYPE_IRQ)
438 			depth++;
439 	}
440 
441 	return depth;
442 }
443 
444 static void diag_append_history(struct bpf_verifier_env *env,
445 				const struct bpf_diag_history_event *event)
446 {
447 	struct bpf_diag_history_event *events;
448 	struct bpf_diag *diag = env->diag;
449 	struct bpf_diag_log *log;
450 	u32 cap, max_events;
451 
452 	if (!diag)
453 		return;
454 	log = &diag->log;
455 
456 	if (log->cnt < log->cap) {
457 		log->events[log_pos(log, log->cnt++)] = *event;
458 		return;
459 	}
460 
461 	max_events = BPF_DIAG_EVENT_LOG_MAX_SIZE / sizeof(*events);
462 	if (log->growth_failed || log->cap == max_events)
463 		goto rotate;
464 
465 	cap = min(log->cap ? log->cap * 2 : 64, max_events);
466 	events = kvrealloc(log->events, array_size(cap, sizeof(*events)), GFP_KERNEL_ACCOUNT);
467 	if (!events) {
468 		log->growth_failed = true;
469 		goto rotate;
470 	}
471 	log->events = events;
472 	log->cap = cap;
473 	log->events[log->cnt++] = *event;
474 	return;
475 
476 rotate:
477 	if (log->cap) {
478 		log->events[log->head++] = *event;
479 		if (log->head == log->cap)
480 			log->head = 0;
481 	}
482 	log->first_seq++;
483 }
484 
485 static void diag_print_wrapped_prefixed(struct bpf_verifier_env *env, const char *first_prefix,
486 					const char *next_prefix, const char *text)
487 {
488 	const char *prefix = first_prefix;
489 
490 	while (*text) {
491 		const char *line = text;
492 		int prefix_len = strlen(prefix);
493 		int text_width = BPF_DIAG_TEXT_WIDTH - prefix_len;
494 		int len = 0, last_space = -1;
495 
496 		if (text_width < 1)
497 			text_width = 1;
498 
499 		while (line[len] && line[len] != '\n' && len < text_width) {
500 			if (line[len] == ' ')
501 				last_space = len;
502 			len++;
503 		}
504 
505 		if (line[len] && line[len] != '\n' && line[len] != ' ' && last_space > 0)
506 			len = last_space;
507 
508 		diag_write(env, "%s%.*s\n", prefix, len, line);
509 
510 		text = line + len;
511 		while (*text == ' ')
512 			text++;
513 		if (*text == '\n')
514 			text++;
515 
516 		prefix = next_prefix;
517 	}
518 }
519 
520 const char *bpf_diag_fmt_btf_type(struct bpf_verifier_env *env, const struct btf *btf, u32 type_id)
521 {
522 	char *buf = bpf_diag_fmt_buf(env, BPF_DIAG_FMT_BUF_SIZE);
523 	size_t len;
524 	int ret;
525 
526 	if (!buf)
527 		return "";
528 
529 	buf[0] = '\0';
530 	ret = btf_type_name_to_buf(btf, type_id, buf, BPF_DIAG_FMT_BUF_SIZE);
531 	if (ret < 0 || !buf[0]) {
532 		scnprintf(buf, BPF_DIAG_FMT_BUF_SIZE, "BTF type ID %u", type_id);
533 		return buf;
534 	}
535 
536 	len = strlen(buf);
537 	if (len && buf[len - 1] == '{')
538 		buf[len - 1] = '\0';
539 	return buf;
540 }
541 
542 static void diag_vprint_indented(struct bpf_verifier_env *env, const char *fmt, va_list args)
543 	__printf(2, 0);
544 
545 static void diag_vprint_indented(struct bpf_verifier_env *env, const char *fmt, va_list args)
546 {
547 	char *buf;
548 
549 	if (!bpf_diag_enabled(env))
550 		return;
551 
552 	buf = kvasprintf(GFP_KERNEL_ACCOUNT, fmt, args);
553 	if (!buf) {
554 		diag_write(env, "%s<failed to allocate diagnostic text>\n", BPF_DIAG_TEXT_INDENT);
555 		return;
556 	}
557 
558 	diag_print_wrapped_prefixed(env, BPF_DIAG_TEXT_INDENT, BPF_DIAG_TEXT_INDENT, buf);
559 	kfree(buf);
560 }
561 
562 static int diag_line_width(unsigned int line)
563 {
564 	int width = 1;
565 
566 	while (line >= 10) {
567 		line /= 10;
568 		width++;
569 	}
570 
571 	return width;
572 }
573 
574 static int diag_line_indent(const char *line)
575 {
576 	int indent = 0;
577 
578 	while (*line == ' ' || *line == '\t') {
579 		if (*line == '\t')
580 			indent = round_up(indent + 1, BPF_DIAG_TAB_WIDTH);
581 		else
582 			indent++;
583 		line++;
584 	}
585 
586 	return indent;
587 }
588 
589 static void disasm_print(void *private_data, const char *fmt, ...) __printf(2, 3);
590 
591 static void disasm_print(void *private_data, const char *fmt, ...)
592 {
593 	struct disasm_ctx *ctx = private_data;
594 	va_list args;
595 
596 	va_start(args, fmt);
597 	seq_buf_vprintf(&ctx->seq, fmt, args);
598 	va_end(args);
599 }
600 
601 static const char *disasm_kfunc_name(void *private_data, const struct bpf_insn *insn)
602 {
603 	struct disasm_ctx *ctx = private_data;
604 
605 	return bpf_disasm_kfunc_name(ctx->env, insn);
606 }
607 
608 static void format_disasm_line(struct bpf_verifier_env *env, int insn_idx,
609 			       struct disasm_line *line)
610 {
611 	struct disasm_ctx ctx = { .env = env };
612 	struct bpf_insn *insn;
613 	const struct bpf_insn_cbs cbs = {
614 		.cb_call = disasm_kfunc_name,
615 		.cb_print = disasm_print,
616 		.private_data = &ctx,
617 	};
618 
619 	line->idx = insn_idx;
620 	line->valid = false;
621 	seq_buf_init(&ctx.seq, line->text, sizeof(line->text));
622 
623 	if (insn_idx < 0 || insn_idx >= env->prog->len)
624 		return;
625 
626 	if (insn_idx > 0 && bpf_is_ldimm64(&env->prog->insnsi[insn_idx - 1]))
627 		return;
628 
629 	insn = &env->prog->insnsi[insn_idx];
630 	if (bpf_is_ldimm64(insn) && insn_idx + 1 >= env->prog->len)
631 		return;
632 
633 	print_bpf_insn(&cbs, insn, env->allow_ptr_leaks);
634 	seq_buf_str(&ctx.seq);
635 	ctx.seq.len = strnlen(line->text, sizeof(line->text));
636 	while (ctx.seq.len && line->text[ctx.seq.len - 1] == '\n')
637 		seq_buf_pop(&ctx.seq);
638 	seq_buf_str(&ctx.seq);
639 
640 	line->valid = true;
641 }
642 
643 static void diag_format_source_text(char *buf, size_t size, const char *line, int width)
644 {
645 	int col = 0, len = 0;
646 
647 	if (!size)
648 		return;
649 	if (width <= 0) {
650 		buf[0] = '\0';
651 		return;
652 	}
653 
654 	line = line ?: "...";
655 	while (*line && col < width && len + 1 < size) {
656 		if (*line == '\t') {
657 			int next = round_up(col + 1, BPF_DIAG_TAB_WIDTH);
658 
659 			while (col < next && col < width && len + 1 < size) {
660 				buf[len++] = ' ';
661 				col++;
662 			}
663 			line++;
664 			continue;
665 		}
666 
667 		buf[len++] = *line++;
668 		col++;
669 	}
670 
671 	if (*line) {
672 		int ellipsis_len = min(3, width);
673 
674 		while (len > 0 && col > width - ellipsis_len) {
675 			len--;
676 			col--;
677 		}
678 		while (ellipsis_len-- && len + 1 < size)
679 			buf[len++] = '.';
680 	}
681 
682 	buf[len] = '\0';
683 }
684 
685 static void diag_format_source_lane(char *buf, size_t size, const char *source_prefix,
686 				    int source_line_width, int line_num, const char *line)
687 {
688 	int len, text_width;
689 
690 	if (line_num <= 0) {
691 		buf[0] = '\0';
692 		return;
693 	}
694 
695 	len = scnprintf(buf, size, "%s%*d | ", source_prefix, source_line_width, line_num);
696 	text_width = BPF_DIAG_SOURCE_LANE_WIDTH - len;
697 	diag_format_source_text(buf + len, size - len, line, text_width);
698 }
699 
700 static void bpf_diag_header(struct bpf_verifier_env *env, const char *category,
701 			    const char *problem)
702 {
703 	char first;
704 
705 	if (!bpf_diag_enabled(env))
706 		return;
707 
708 	category = category ?: "Verifier Error";
709 	problem = problem ?: "";
710 
711 	if (!problem[0]) {
712 		diag_write(env, "\nVerification failed: %s\n", category);
713 		return;
714 	}
715 
716 	first = toupper(problem[0]);
717 	diag_write(env, "\nVerification failed: %s: %c%s\n", category, first, problem + 1);
718 }
719 
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, ...)
722 	__printf(2, 3);
723 
724 static void diag_section(struct bpf_verifier_env *env, const char *title)
725 {
726 	if (!bpf_diag_enabled(env))
727 		return;
728 
729 	diag_write(env, "\n%s:\n", title);
730 }
731 
732 static void diag_reason(struct bpf_verifier_env *env, const char *fmt, ...)
733 {
734 	va_list args;
735 
736 	if (!bpf_diag_enabled(env))
737 		return;
738 
739 	diag_section(env, "Reason");
740 
741 	va_start(args, fmt);
742 	diag_vprint_indented(env, fmt, args);
743 	va_end(args);
744 }
745 
746 static void diag_suggestion(struct bpf_verifier_env *env, const char *fmt, ...)
747 {
748 	va_list args;
749 
750 	if (!bpf_diag_enabled(env))
751 		return;
752 
753 	diag_section(env, "Suggestion");
754 
755 	va_start(args, fmt);
756 	diag_vprint_indented(env, fmt, args);
757 	va_end(args);
758 	diag_write(env, "\n");
759 }
760 
761 static void diag_print_source_annotation(struct bpf_verifier_env *env, int line_width, int indent,
762 					 const char *label, const char *msg)
763 {
764 	const char *first_prefix, *next_prefix, *text;
765 
766 	indent = min_t(int, indent, max_t(int, 0, BPF_DIAG_SOURCE_LANE_WIDTH - line_width - 8));
767 	text = bpf_diag_fmt(env, "%s: %s", label, msg);
768 	first_prefix = bpf_diag_fmt(env, "  %*s | %*s^-- ", line_width + 4, "", indent, "");
769 	next_prefix = bpf_diag_fmt(env, "  %*s | %*s    ", line_width + 4, "", indent, "");
770 
771 	diag_print_wrapped_prefixed(env, first_prefix, next_prefix, text);
772 }
773 
774 static void diag_print_insn_context(struct bpf_verifier_env *env, u32 insn_idx,
775 				    struct disasm_line *disasm_lines)
776 {
777 	int insn_width = diag_line_width(env->prog->len ? env->prog->len - 1 : 0);
778 	int i;
779 
780 	for (i = 0; i < BPF_DIAG_CONTEXT_CNT; i++) {
781 		int row = i - BPF_DIAG_CONTEXT;
782 
783 		format_disasm_line(env, insn_idx + row, &disasm_lines[i]);
784 	}
785 
786 	diag_write(env, "  Instruction context:\n");
787 	for (i = 0; i < BPF_DIAG_CONTEXT_CNT; i++) {
788 		struct disasm_line *line = &disasm_lines[i];
789 
790 		if (line->valid)
791 			diag_write(env, "  %s%*d | %s\n",
792 				   line->idx == insn_idx ? ">>> " : "    ",
793 				   insn_width, line->idx, line->text);
794 	}
795 }
796 
797 static void bpf_diag_source(struct bpf_verifier_env *env, u32 insn_idx, const char *label,
798 			    const char *fmt, ...)
799 {
800 	struct bpf_diag_scratch *scratch;
801 	struct bpf_linfo_source *source_lines;
802 	struct disasm_line *disasm_lines;
803 	struct bpf_linfo_source src = {};
804 	struct diag_fmt_mark mark;
805 	const struct bpf_line_info *linfo;
806 	const struct bpf_subprog_info *subprog;
807 	struct btf *btf = env->prog->aux->btf;
808 	char *source_lane;
809 	const char *msg;
810 	const char *func;
811 	int start_line, end_line, width, indent, subprogno, linfo_start, linfo_end, i;
812 	va_list args;
813 
814 	if (!bpf_diag_enabled(env))
815 		return;
816 	if (!env->diag)
817 		return;
818 
819 	mark = diag_fmt_save(env);
820 	label = label ?: "note";
821 	scratch = &env->diag->scratch;
822 	source_lines = scratch->source_lines;
823 	disasm_lines = scratch->disasm_lines;
824 	memset(source_lines, 0, sizeof(scratch->source_lines));
825 	memset(disasm_lines, 0, sizeof(scratch->disasm_lines));
826 
827 	va_start(args, fmt);
828 	msg = bpf_diag_vfmt(env, fmt, args);
829 	va_end(args);
830 	if (!*msg)
831 		msg = "<failed to allocate diagnostic text>";
832 
833 	linfo = bpf_find_linfo(env->prog, insn_idx);
834 	if (btf && linfo)
835 		bpf_get_linfo_source(btf, linfo, &src);
836 	if (!src.file || !*src.file || !src.line || !*src.line) {
837 		diag_write(env, "  insn %u\n", insn_idx);
838 		diag_print_source_annotation(env, 0, 0, label, msg);
839 		diag_print_insn_context(env, insn_idx, disasm_lines);
840 		goto out_restore;
841 	}
842 
843 	subprog = bpf_find_containing_subprog(env, insn_idx);
844 	subprogno = subprog ? subprog - env->subprog_info : -ENOENT;
845 	func = subprogno >= 0 ? bpf_subprog_name(env, subprogno) : NULL;
846 	if (func && *func)
847 		diag_write(env, "  %s @ %s:%d:%d\n", func, src.file, src.line_num, src.line_col);
848 	else
849 		diag_write(env, "  %s:%d:%d\n", src.file, src.line_num, src.line_col);
850 
851 	start_line = src.line_num - BPF_DIAG_CONTEXT;
852 	end_line = src.line_num + BPF_DIAG_CONTEXT;
853 	width = diag_line_width(end_line);
854 	indent = diag_line_indent(src.line);
855 	for (i = 0; i < BPF_DIAG_CONTEXT_CNT; i++)
856 		source_lines[i].line_num = start_line + i;
857 
858 	linfo = env->prog->aux->linfo;
859 	linfo_start = subprog ? subprog->linfo_idx : 0;
860 	linfo_end = subprogno >= 0 && subprogno + 1 < env->subprog_cnt ?
861 		    env->subprog_info[subprogno + 1].linfo_idx : env->prog->aux->nr_linfo;
862 	for (i = linfo_start; i < linfo_end; i++) {
863 		struct bpf_linfo_source line_src;
864 		int idx;
865 
866 		bpf_get_linfo_source(btf, &linfo[i], &line_src);
867 		if (line_src.file_name_off != src.file_name_off ||
868 		    line_src.line_num < start_line || line_src.line_num > end_line ||
869 		    !line_src.line || !*line_src.line)
870 			continue;
871 
872 		idx = line_src.line_num - start_line;
873 		if (!source_lines[idx].line)
874 			source_lines[idx] = line_src;
875 	}
876 
877 	diag_write(env, "  Source context:\n");
878 	source_lane = bpf_diag_fmt_buf(env, BPF_DIAG_FMT_BUF_SIZE);
879 	if (!source_lane)
880 		goto out_restore;
881 	for (i = 0; i < BPF_DIAG_CONTEXT_CNT; i++) {
882 		const char *source_prefix;
883 
884 		source_prefix = source_lines[i].line_num == src.line_num ? ">>> " : "    ";
885 		diag_format_source_lane(source_lane, BPF_DIAG_FMT_BUF_SIZE, source_prefix, width,
886 					source_lines[i].line_num, source_lines[i].line);
887 		diag_write(env, "  %s\n", source_lane);
888 		if (source_lines[i].line_num == src.line_num)
889 			diag_print_source_annotation(env, width, indent, label, msg);
890 	}
891 	diag_print_insn_context(env, insn_idx, disasm_lines);
892 
893 out_restore:
894 	diag_fmt_restore(env, mark);
895 }
896 
897 static const struct bpf_func_state *diag_current_frame(const struct bpf_verifier_env *env)
898 {
899 	return env->cur_state->frame[env->cur_state->curframe];
900 }
901 
902 void bpf_diag_register_type(struct bpf_verifier_env *env, u32 insn_idx, int regno,
903 			    const char *problem, const char *reason, const char *suggestion)
904 {
905 	const struct bpf_func_state *frame = diag_current_frame(env);
906 	struct bpf_diag_history_opts opts = {
907 		.scope = BPF_DIAG_HISTORY_SCOPE_REG,
908 		.frame_id = frame->diag_frame_id,
909 		.frameno = frame->frameno,
910 		.regno = regno,
911 	};
912 
913 	bpf_diag_header(env, REGISTER_TYPE_SAFETY, problem);
914 	diag_reason(env, "%s", reason);
915 
916 	diag_section(env, "At");
917 	bpf_diag_source(env, insn_idx, "error", "%s", problem);
918 
919 	if (regno >= 0)
920 		diag_print_history(env, &opts);
921 
922 	diag_suggestion(env, "%s", suggestion);
923 }
924 
925 const char *bpf_diag_reg_type_plain(struct bpf_verifier_env *env, enum bpf_reg_type type)
926 {
927 	switch (base_type(type)) {
928 	case NOT_INIT:
929 		return "an uninitialized value";
930 	case SCALAR_VALUE:
931 		return "an integer scalar";
932 	case PTR_TO_CTX:
933 		return "a context pointer";
934 	case PTR_TO_STACK:
935 		return "a stack pointer";
936 	case PTR_TO_MAP_VALUE:
937 		if (type_may_be_null(type))
938 			return "a nullable map value pointer";
939 		return "a map value pointer";
940 	case PTR_TO_MEM:
941 		if (type_may_be_null(type))
942 			return "a nullable memory pointer";
943 		return "a memory pointer";
944 	case PTR_TO_BTF_ID:
945 		if (type_may_be_null(type))
946 			return "a nullable kernel object pointer";
947 		if (type_is_non_owning_ref(type))
948 			return "a borrowed allocated object pointer";
949 		if (type_is_ptr_alloc_obj(type))
950 			return "an owned allocated object pointer";
951 		if (type_flag(type) & PTR_UNTRUSTED)
952 			return "an untrusted kernel object pointer";
953 		return "a kernel object pointer";
954 	default:
955 		return reg_type_str(env, type);
956 	}
957 }
958 
959 static const char *diag_arg_ordinal(int argno)
960 {
961 	switch (argno) {
962 	case 1:
963 		return "first";
964 	case 2:
965 		return "second";
966 	case 3:
967 		return "third";
968 	case 4:
969 		return "fourth";
970 	case 5:
971 		return "fifth";
972 	case 6:
973 		return "sixth";
974 	case 7:
975 		return "seventh";
976 	case 8:
977 		return "eighth";
978 	case 9:
979 		return "ninth";
980 	case 10:
981 		return "tenth";
982 	case 11:
983 		return "eleventh";
984 	case 12:
985 		return "twelfth";
986 	default:
987 		return NULL;
988 	}
989 }
990 
991 void bpf_diag_call_type(struct bpf_verifier_env *env, u32 insn_idx, int argno, int regno,
992 			int stack_arg_slot, const char *call_name, const char *arg_name,
993 			const char *reason, const char *suggestion)
994 {
995 	const struct bpf_func_state *frame = diag_current_frame(env);
996 	struct bpf_diag_history_opts opts = {
997 		.frame_id = frame->diag_frame_id,
998 		.frameno = frame->frameno,
999 	};
1000 	const char *ordinal = diag_arg_ordinal(argno);
1001 	const char *arg_desc;
1002 	bool print_history = true;
1003 
1004 	if (regno >= 0) {
1005 		opts.scope = BPF_DIAG_HISTORY_SCOPE_REG;
1006 		opts.regno = regno;
1007 	} else if (stack_arg_slot >= 0) {
1008 		opts.scope = BPF_DIAG_HISTORY_SCOPE_STACK_ARG;
1009 		opts.stack_arg_slot = stack_arg_slot;
1010 	} else {
1011 		print_history = false;
1012 	}
1013 
1014 	if (ordinal && arg_name)
1015 		arg_desc = bpf_diag_fmt(env, "%s argument (%s)", ordinal, arg_name);
1016 	else if (ordinal)
1017 		arg_desc = bpf_diag_fmt(env, "%s argument", ordinal);
1018 	else if (arg_name)
1019 		arg_desc = bpf_diag_fmt(env, "argument %s", arg_name);
1020 	else
1021 		arg_desc = "argument";
1022 
1023 	bpf_diag_header(env, CALL_TYPE_SAFETY, "invalid call argument");
1024 	diag_reason(env, "The %s to %s does not satisfy the verifier contract: %s.",
1025 		    arg_desc, call_name, reason);
1026 
1027 	diag_section(env, "At");
1028 	bpf_diag_source(env, insn_idx, "error", "invalid %s for %s", arg_desc, call_name);
1029 
1030 	if (print_history)
1031 		diag_print_history(env, &opts);
1032 
1033 	diag_suggestion(env, "%s", suggestion);
1034 }
1035 
1036 static const char *diag_context_constraint(enum bpf_diag_context_kind kind)
1037 {
1038 	switch (kind) {
1039 	case BPF_DIAG_CONTEXT_RCU:
1040 		return "RCU read-side critical sections cannot call operations that may sleep";
1041 	case BPF_DIAG_CONTEXT_PREEMPT:
1042 		return "preemption-disabled code cannot call operations that may sleep";
1043 	case BPF_DIAG_CONTEXT_IRQ:
1044 		return "IRQ-disabled code cannot call operations that may sleep";
1045 	case BPF_DIAG_CONTEXT_LOCK:
1046 		return "code holding a BPF spin lock cannot call operations that may sleep";
1047 	case BPF_DIAG_CONTEXT_NONE:
1048 	default:
1049 		return NULL;
1050 	}
1051 }
1052 
1053 static const char *diag_active_context(struct bpf_verifier_env *env, u32 depth,
1054 				       const char *context)
1055 {
1056 	if (depth == 1)
1057 		return bpf_diag_fmt(env, "an active %s (depth 1)", context);
1058 	return bpf_diag_fmt(env, "%u active %ss (depth %u)", depth, context, depth);
1059 }
1060 
1061 static u32 diag_context_depth(struct bpf_verifier_env *env, enum bpf_diag_context_kind kind)
1062 {
1063 	switch (kind) {
1064 	case BPF_DIAG_CONTEXT_RCU:
1065 		return env->cur_state->active_rcu_locks;
1066 	case BPF_DIAG_CONTEXT_PREEMPT:
1067 		return env->cur_state->active_preempt_locks;
1068 	case BPF_DIAG_CONTEXT_IRQ:
1069 		return bpf_diag_irq_depth(env->cur_state);
1070 	case BPF_DIAG_CONTEXT_LOCK:
1071 		return env->cur_state->active_locks;
1072 	case BPF_DIAG_CONTEXT_NONE:
1073 	default:
1074 		return 0;
1075 	}
1076 }
1077 
1078 void bpf_diag_ctx_forbidden(struct bpf_verifier_env *env, u32 insn_idx,
1079 			    const char *operation, const char *suggestion)
1080 {
1081 	struct bpf_diag_history_opts opts;
1082 	enum bpf_diag_context_kind ctx_kind;
1083 	const char *constraint, *context;
1084 	u32 depth;
1085 
1086 	if (env->cur_state->active_rcu_locks)
1087 		ctx_kind = BPF_DIAG_CONTEXT_RCU;
1088 	else if (env->cur_state->active_preempt_locks)
1089 		ctx_kind = BPF_DIAG_CONTEXT_PREEMPT;
1090 	else if (env->cur_state->active_irq_id)
1091 		ctx_kind = BPF_DIAG_CONTEXT_IRQ;
1092 	else if (env->cur_state->active_locks)
1093 		ctx_kind = BPF_DIAG_CONTEXT_LOCK;
1094 	else
1095 		ctx_kind = BPF_DIAG_CONTEXT_NONE;
1096 
1097 	depth = diag_context_depth(env, ctx_kind);
1098 	opts = (struct bpf_diag_history_opts) {
1099 		.scope = BPF_DIAG_HISTORY_SCOPE_CONTEXT,
1100 		.ctx_kind = ctx_kind,
1101 		.ctx_depth = depth,
1102 	};
1103 	constraint = diag_context_constraint(ctx_kind);
1104 	context = diag_context_name(ctx_kind);
1105 
1106 	bpf_diag_header(env, EXECUTION_CONTEXT_SAFETY,
1107 			"operation is not allowed in this context");
1108 	if (constraint) {
1109 		if (depth) {
1110 			diag_reason(
1111 				env, "The operation %s cannot be used in %s because %s. This path is still inside %s.",
1112 				operation, context, constraint, diag_active_context(env, depth, context));
1113 		} else {
1114 			diag_reason(env, "The operation %s cannot be used in %s because %s.",
1115 				    operation, context, constraint);
1116 		}
1117 	} else {
1118 		diag_reason(env, "The operation %s cannot be used in %s.", operation,
1119 			    context);
1120 	}
1121 
1122 	diag_section(env, "At");
1123 	bpf_diag_source(env, insn_idx, "error", "%s is not allowed in %s", operation,
1124 			context);
1125 
1126 	if (ctx_kind != BPF_DIAG_CONTEXT_NONE)
1127 		diag_print_history(env, &opts);
1128 
1129 	diag_suggestion(env, "%s", suggestion);
1130 }
1131 
1132 void bpf_diag_ctx_active(struct bpf_verifier_env *env, u32 insn_idx, const char *operation,
1133 			 enum bpf_diag_context_kind ctx_kind, const char *suggestion)
1134 {
1135 	u32 depth = diag_context_depth(env, ctx_kind);
1136 	struct bpf_diag_history_opts opts = {
1137 		.scope = BPF_DIAG_HISTORY_SCOPE_CONTEXT,
1138 		.ctx_kind = ctx_kind,
1139 		.ctx_depth = depth,
1140 	};
1141 	const char *context = diag_context_name(ctx_kind);
1142 
1143 	bpf_diag_header(env, EXECUTION_CONTEXT_SAFETY,
1144 			"operation is not allowed in this context");
1145 	diag_reason(
1146 		env, "The operation %s cannot be used while this path is still inside %s. Leave the region before this operation.",
1147 		operation, diag_active_context(env, depth, context));
1148 
1149 	diag_section(env, "At");
1150 	bpf_diag_source(env, insn_idx, "error", "%s is not allowed before leaving %s",
1151 			operation, context);
1152 
1153 	diag_print_history(env, &opts);
1154 
1155 	diag_suggestion(env, "%s", suggestion);
1156 }
1157 
1158 void bpf_diag_ctx_required(struct bpf_verifier_env *env, u32 insn_idx, const char *operation,
1159 			   enum bpf_diag_context_kind ctx_kind, const char *suggestion)
1160 {
1161 	const char *context = diag_context_name(ctx_kind);
1162 
1163 	bpf_diag_header(env, EXECUTION_CONTEXT_SAFETY, "required context is not active");
1164 	diag_reason(env, "The operation %s requires an active %s, but this path is outside one.",
1165 		    operation, context);
1166 
1167 	diag_section(env, "At");
1168 	bpf_diag_source(env, insn_idx, "error", "%s requires %s", operation, context);
1169 
1170 	diag_suggestion(env, "%s", suggestion);
1171 }
1172 
1173 void bpf_diag_ctx_underflow(struct bpf_verifier_env *env, u32 insn_idx,
1174 			    const char *operation, enum bpf_diag_context_kind ctx_kind,
1175 			    const char *suggestion)
1176 {
1177 	struct bpf_diag_history_opts opts = {
1178 		.scope = BPF_DIAG_HISTORY_SCOPE_CONTEXT,
1179 		.ctx_kind = ctx_kind,
1180 	};
1181 	const char *context = diag_context_name(ctx_kind);
1182 
1183 	bpf_diag_header(env, EXECUTION_CONTEXT_SAFETY, "unmatched context exit");
1184 	diag_reason(
1185 		env, "The operation %s tries to leave %s, but this path has no active %s to leave. The current depth is 0.",
1186 		operation, context, context);
1187 
1188 	diag_section(env, "At");
1189 	bpf_diag_source(env, insn_idx, "error", "%s has no matching enter on this path",
1190 			operation);
1191 
1192 	diag_print_history(env, &opts);
1193 
1194 	diag_suggestion(env, "%s", suggestion);
1195 }
1196 
1197 void bpf_diag_program_structure(struct bpf_verifier_env *env, u32 insn_idx,
1198 				const char *problem, const char *suggestion,
1199 				const char *reason_fmt, ...)
1200 {
1201 	va_list args;
1202 
1203 	bpf_diag_header(env, PROGRAM_STRUCTURE, problem);
1204 	diag_section(env, "Reason");
1205 
1206 	va_start(args, reason_fmt);
1207 	diag_vprint_indented(env, reason_fmt, args);
1208 	va_end(args);
1209 
1210 	diag_section(env, "At");
1211 	bpf_diag_source(env, insn_idx, "error", "%s", problem);
1212 
1213 	diag_suggestion(env, "%s", suggestion);
1214 }
1215 
1216 void bpf_diag_policy(struct bpf_verifier_env *env, u32 insn_idx, const char *operation,
1217 		     const char *reason, const char *suggestion)
1218 {
1219 	bpf_diag_header(env, POLICY, "operation is not allowed");
1220 	diag_reason(env, "The %s is not allowed: %s.", operation, reason);
1221 
1222 	diag_section(env, "At");
1223 	bpf_diag_source(env, insn_idx, "error", "policy check failed for %s", operation);
1224 
1225 	diag_suggestion(env, "%s", suggestion);
1226 }
1227 
1228 void bpf_diag_invalid_deref(struct bpf_verifier_env *env, u32 insn_idx, int regno,
1229 			    const char *reg_name, const struct bpf_reg_state *reg,
1230 			    enum bpf_diag_invalid_deref_kind kind, s64 offset)
1231 {
1232 	const struct bpf_func_state *frame = diag_current_frame(env);
1233 	struct bpf_diag_history_opts opts = {
1234 		.scope = BPF_DIAG_HISTORY_SCOPE_REG,
1235 		.frame_id = frame->diag_frame_id,
1236 		.frameno = frame->frameno,
1237 		.regno = regno,
1238 	};
1239 	const char *type_name = bpf_diag_reg_type_plain(env, reg->type);
1240 
1241 	bpf_diag_header(env, REGISTER_TYPE_SAFETY, "invalid dereference");
1242 
1243 	switch (kind) {
1244 	case BPF_DIAG_DEREF_SCALAR:
1245 		diag_reason(env, "%s is an integer scalar here, not a pointer to memory.",
1246 			    reg_name);
1247 		break;
1248 	case BPF_DIAG_DEREF_NULLABLE_PTR:
1249 		diag_reason(
1250 			env, "%s may be NULL here (%s). The program could dereference NULL on this path, so the verifier cannot prove this access is safe.",
1251 			reg_name, type_name);
1252 		break;
1253 	case BPF_DIAG_DEREF_MODIFIED_PTR:
1254 		diag_reason(
1255 			env, "%s has offset %lld here, but this pointer type must be dereferenced in its original form.",
1256 			reg_name, offset);
1257 		break;
1258 	case BPF_DIAG_DEREF_INVALID_PTR:
1259 	default:
1260 		diag_reason(
1261 			env, "%s has type %s here, which is not valid for this memory access.",
1262 			reg_name, type_name);
1263 		break;
1264 	}
1265 
1266 	diag_section(env, "At");
1267 	if (kind == BPF_DIAG_DEREF_MODIFIED_PTR)
1268 		bpf_diag_source(env, insn_idx, "error",
1269 				"dereference requires the original %s pointer", type_name);
1270 	else
1271 		bpf_diag_source(env, insn_idx, "error", "invalid dereference of %s (%s)",
1272 				reg_name, type_name);
1273 
1274 	if (regno >= 0)
1275 		diag_print_history(env, &opts);
1276 
1277 	switch (kind) {
1278 	case BPF_DIAG_DEREF_NULLABLE_PTR:
1279 		diag_suggestion(
1280 			env, "Add a NULL check before the access and dereference the pointer only on the non-NULL path.");
1281 		break;
1282 	case BPF_DIAG_DEREF_MODIFIED_PTR:
1283 		diag_suggestion(
1284 			env, "Preserve the original pointer in another register, or use only offsets this pointer type permits before dereferencing it.");
1285 		break;
1286 	case BPF_DIAG_DEREF_SCALAR:
1287 	case BPF_DIAG_DEREF_INVALID_PTR:
1288 	default:
1289 		diag_suggestion(
1290 			env, "Preserve a pointer-valued register where needed, or reload and revalidate the pointer after scalar arithmetic, helper calls, or other operations that can invalidate it.");
1291 		break;
1292 	}
1293 }
1294 
1295 void bpf_diag_unreadable_reg(struct bpf_verifier_env *env, u32 insn_idx, int regno)
1296 {
1297 	const struct bpf_func_state *frame = diag_current_frame(env);
1298 	struct bpf_diag_history_opts opts = {
1299 		.scope = BPF_DIAG_HISTORY_SCOPE_REG,
1300 		.frame_id = frame->diag_frame_id,
1301 		.frameno = frame->frameno,
1302 		.regno = regno,
1303 	};
1304 	const struct bpf_diag_log *log = env->diag ? &env->diag->log : NULL;
1305 	struct bpf_diag_mod_target target;
1306 	bool invalidated = false;
1307 	int i;
1308 
1309 	target = diag_reg_target(opts.frame_id, opts.frameno, regno);
1310 	for (i = log ? log->cnt : 0; i > 0; i--) {
1311 		const struct bpf_diag_history_event *event;
1312 
1313 		event = &log->events[log_pos(log, i - 1)];
1314 
1315 		if (event->kind != BPF_DIAG_HISTORY_MOD ||
1316 		    !diag_target_matches(&event->mod.target, &target))
1317 			continue;
1318 		invalidated = event->mod.new.type == NOT_INIT;
1319 		break;
1320 	}
1321 
1322 	bpf_diag_header(env, REGISTER_TYPE_SAFETY, "unreadable register");
1323 	if (invalidated)
1324 		diag_reason(
1325 			env, "R%d is not readable here. A previous operation invalidated this register, so the verifier cannot use it as an input.",
1326 			regno);
1327 	else if (log && !log->first_seq)
1328 		diag_reason(env,
1329 			    "R%d has never been initialized on this path, so the verifier cannot use it as an input.",
1330 			    regno);
1331 	else
1332 		diag_reason(
1333 			env, "R%d is not readable here. It may never have been initialized, or an earlier operation may have invalidated it.",
1334 			regno);
1335 
1336 	diag_section(env, "At");
1337 	bpf_diag_source(env, insn_idx, "error", "R%d is not readable", regno);
1338 
1339 	if (regno >= 0)
1340 		diag_print_history(env, &opts);
1341 
1342 	if (invalidated)
1343 		diag_suggestion(
1344 			env, "Avoid using the register after it is invalidated, or initialize it again before this instruction.");
1345 	else if (log && !log->first_seq)
1346 		diag_suggestion(env, "Initialize R%d on every path before this instruction.", regno);
1347 	else
1348 		diag_suggestion(
1349 			env, "Initialize the register on every path, or initialize it again after any operation that invalidates it.");
1350 }
1351 
1352 static int diag_stack_argno(u8 slot)
1353 {
1354 	return MAX_BPF_FUNC_REG_ARGS + slot + 1;
1355 }
1356 
1357 static void diag_format_stack_arg(char *buf, size_t size, u8 slot, const char *arg_name)
1358 {
1359 	int argno = diag_stack_argno(slot);
1360 	const char *ordinal = diag_arg_ordinal(argno);
1361 
1362 	if (ordinal && arg_name)
1363 		scnprintf(buf, size, "outgoing stack argument %u (%s argument, %s)", slot + 1,
1364 			  ordinal, arg_name);
1365 	else if (ordinal)
1366 		scnprintf(buf, size, "outgoing stack argument %u (%s argument)", slot + 1, ordinal);
1367 	else if (arg_name)
1368 		scnprintf(buf, size, "outgoing stack argument %u (%s)", slot + 1, arg_name);
1369 	else
1370 		scnprintf(buf, size, "outgoing stack argument %u", slot + 1);
1371 }
1372 
1373 void bpf_diag_stack_arg_uninit(struct bpf_verifier_env *env, u32 insn_idx, int nargs,
1374 			       int stack_arg_slot, const char *callee_name,
1375 			       const char *arg_name)
1376 {
1377 	const struct bpf_func_state *frame = diag_current_frame(env);
1378 	struct bpf_diag_history_opts opts = {
1379 		.scope = BPF_DIAG_HISTORY_SCOPE_STACK_ARG,
1380 		.frame_id = frame->diag_frame_id,
1381 		.frameno = frame->frameno,
1382 		.stack_arg_slot = stack_arg_slot,
1383 	};
1384 	const char *arg_buf;
1385 
1386 	arg_buf = bpf_diag_fmt_buf(env, BPF_DIAG_FMT_BUF_SIZE);
1387 	if (arg_buf)
1388 		diag_format_stack_arg((char *)arg_buf, BPF_DIAG_FMT_BUF_SIZE, stack_arg_slot,
1389 				      arg_name);
1390 	else
1391 		arg_buf = "";
1392 	bpf_diag_header(env, REGISTER_TYPE_SAFETY, "missing stack argument");
1393 	if (callee_name && *callee_name)
1394 		diag_reason(
1395 			env, "Function %s expects %d arguments, but %s is not initialized at this call.",
1396 			callee_name, nargs, arg_buf);
1397 	else
1398 		diag_reason(
1399 			env, "The callee expects %d arguments, but %s is not initialized at this call.",
1400 			nargs, arg_buf);
1401 
1402 	diag_section(env, "At");
1403 	bpf_diag_source(env, insn_idx, "error", "%s is not initialized", arg_buf);
1404 
1405 	if (stack_arg_slot >= 0)
1406 		diag_print_history(env, &opts);
1407 
1408 	diag_suggestion(
1409 		env, "Write the outgoing stack argument after any operation that may invalidate stored pointer values, and before making this call.");
1410 }
1411 
1412 void bpf_diag_memory(struct bpf_verifier_env *env, u32 insn_idx, const char *problem,
1413 		     const char *reason, const char *suggestion)
1414 {
1415 	bpf_diag_header(env, MEMORY_SAFETY, problem);
1416 	diag_reason(env, "%s", reason);
1417 
1418 	diag_section(env, "At");
1419 	bpf_diag_source(env, insn_idx, "error", "%s", problem);
1420 
1421 	diag_suggestion(env, "%s", suggestion);
1422 }
1423 
1424 void bpf_diag_record_branch(struct bpf_verifier_env *env, u32 insn_idx, bool cond_true)
1425 {
1426 	struct bpf_diag_history_event event = {
1427 		.insn_idx = insn_idx,
1428 		.kind = BPF_DIAG_HISTORY_BRANCH,
1429 		.branch = {
1430 			.cond_true = cond_true,
1431 		},
1432 	};
1433 
1434 	diag_append_history(env, &event);
1435 }
1436 
1437 static void diag_snapshot_reg(struct bpf_diag_reg_snapshot *snapshot,
1438 			      const struct bpf_reg_state *reg)
1439 {
1440 	snapshot->type = reg->type;
1441 	if (type_is_map_ptr(reg->type))
1442 		snapshot->map_ptr = reg->map_ptr;
1443 	if (base_type(reg->type) == PTR_TO_BTF_ID && reg->btf && reg->btf_id) {
1444 		snapshot->btf_id = reg->btf_id;
1445 		snapshot->btf = reg->btf;
1446 	}
1447 	snapshot->var_off = reg->var_off;
1448 	snapshot->r64 = reg->r64;
1449 }
1450 
1451 static bool diag_mod_insn_origin(struct bpf_verifier_env *env, u32 insn_idx,
1452 				 const struct bpf_diag_mod_target *target,
1453 				 struct bpf_diag_mod_target *origin)
1454 {
1455 	const struct bpf_insn *insn = &env->prog->insnsi[insn_idx];
1456 	u8 class = BPF_CLASS(insn->code);
1457 	const struct bpf_func_state *state;
1458 
1459 	if (target->kind == BPF_DIAG_MOD_TARGET_REG && (class == BPF_ALU || class == BPF_ALU64) &&
1460 	    BPF_OP(insn->code) == BPF_MOV && BPF_SRC(insn->code) == BPF_X) {
1461 		*origin = diag_reg_target(target->frame_id, target->frameno, insn->src_reg);
1462 		return true;
1463 	}
1464 
1465 	if ((target->kind != BPF_DIAG_MOD_TARGET_STACK_ARG &&
1466 	     target->kind != BPF_DIAG_MOD_TARGET_STACK_SLOT) ||
1467 	    class != BPF_STX)
1468 		return false;
1469 
1470 	state = env->cur_state->frame[env->cur_state->curframe];
1471 	*origin = diag_reg_target(state->diag_frame_id, state->frameno, insn->src_reg);
1472 	return true;
1473 }
1474 
1475 static bool diag_mod_keeps_lineage(struct bpf_verifier_env *env,
1476 				   const struct bpf_diag_history_event *event)
1477 {
1478 	const struct bpf_insn *insn;
1479 	u8 class;
1480 
1481 	if (event->mod.reason != BPF_DIAG_MOD_WRITE ||
1482 	    event->mod.target.kind != BPF_DIAG_MOD_TARGET_REG)
1483 		return false;
1484 
1485 	insn = &env->prog->insnsi[event->insn_idx];
1486 	class = BPF_CLASS(insn->code);
1487 	if (class != BPF_ALU && class != BPF_ALU64)
1488 		return false;
1489 
1490 	switch (BPF_OP(insn->code)) {
1491 	case BPF_ADD:
1492 	case BPF_SUB:
1493 	case BPF_MUL:
1494 	case BPF_OR:
1495 	case BPF_AND:
1496 	case BPF_LSH:
1497 	case BPF_RSH:
1498 	case BPF_ARSH:
1499 	case BPF_XOR:
1500 	case BPF_NEG:
1501 	case BPF_END:
1502 		return true;
1503 	default:
1504 		return false;
1505 	}
1506 }
1507 
1508 static void diag_record_mod(struct bpf_verifier_env *env, u32 insn_idx,
1509 			    struct bpf_diag_mod_target target,
1510 			    enum bpf_diag_mod_reason reason,
1511 			    const struct bpf_reg_state *old_reg,
1512 			    const struct bpf_reg_state *new_reg,
1513 			    const struct bpf_diag_mod_target *origin)
1514 {
1515 	struct bpf_diag_history_event event = {
1516 		.insn_idx = insn_idx,
1517 		.kind = BPF_DIAG_HISTORY_MOD,
1518 		.mod = {
1519 			.target = target,
1520 			.reason = reason,
1521 		},
1522 	};
1523 
1524 	if (old_reg)
1525 		diag_snapshot_reg(&event.mod.old, old_reg);
1526 	if (new_reg)
1527 		diag_snapshot_reg(&event.mod.new, new_reg);
1528 	if (origin) {
1529 		event.mod.origin = *origin;
1530 		event.mod.origin_valid = true;
1531 	} else if (diag_mod_insn_origin(env, insn_idx, &target, &event.mod.origin)) {
1532 		event.mod.origin_valid = true;
1533 	}
1534 	if (old_reg && new_reg &&
1535 	    (reason == BPF_DIAG_MOD_WRITE || reason == BPF_DIAG_MOD_SPILL) &&
1536 	    !memcmp(&event.mod.old, &event.mod.new, sizeof(event.mod.old)) &&
1537 	    !event.mod.origin_valid &&
1538 	    diag_mod_keeps_lineage(env, &event))
1539 		return;
1540 
1541 	diag_append_history(env, &event);
1542 }
1543 
1544 static struct bpf_reg_state *target_to_reg(struct bpf_verifier_env *env,
1545 					   const struct bpf_diag_mod_target *target)
1546 {
1547 	struct bpf_verifier_state *vstate = env->cur_state;
1548 	struct bpf_func_state *state;
1549 
1550 	state = target->frameno <= vstate->curframe ? vstate->frame[target->frameno] : NULL;
1551 
1552 	if (!state)
1553 		return NULL;
1554 	if (state->diag_frame_id != target->frame_id)
1555 		return NULL;
1556 
1557 	switch (target->kind) {
1558 	case BPF_DIAG_MOD_TARGET_REG:
1559 		if (target->regno >= MAX_BPF_REG)
1560 			return NULL;
1561 		return &state->regs[target->regno];
1562 	case BPF_DIAG_MOD_TARGET_STACK_ARG:
1563 		if (target->stack_arg >= state->out_stack_arg_cnt)
1564 			return NULL;
1565 		return &state->stack_arg_regs[target->stack_arg];
1566 	case BPF_DIAG_MOD_TARGET_STACK_SLOT:
1567 		if (target->spi >= state->allocated_stack / BPF_REG_SIZE)
1568 			return NULL;
1569 		return &state->stack[target->spi].spilled_ptr;
1570 	default:
1571 		return NULL;
1572 	}
1573 }
1574 
1575 static bool reg_to_target(struct bpf_verifier_env *env, const struct bpf_reg_state *reg,
1576 			  struct bpf_diag_mod_target *target)
1577 {
1578 	struct bpf_verifier_state *vstate = env->cur_state;
1579 	unsigned long addr = (unsigned long)reg;
1580 	int frame;
1581 
1582 	for (frame = 0; frame <= vstate->curframe; frame++) {
1583 		struct bpf_func_state *state = vstate->frame[frame];
1584 		unsigned long start, end;
1585 		u32 nslots = state->allocated_stack / BPF_REG_SIZE;
1586 		int spi;
1587 
1588 		start = (unsigned long)state->regs;
1589 		end = (unsigned long)(state->regs + MAX_BPF_REG);
1590 		if (addr >= start && addr < end) {
1591 			*target = diag_reg_target(state->diag_frame_id, state->frameno,
1592 						  reg - state->regs);
1593 			return true;
1594 		}
1595 
1596 		start = (unsigned long)state->stack_arg_regs;
1597 		end = (unsigned long)(state->stack_arg_regs + state->out_stack_arg_cnt);
1598 		if (state->out_stack_arg_cnt && addr >= start && addr < end) {
1599 			*target = diag_stack_arg_target(state->diag_frame_id, state->frameno,
1600 							reg - state->stack_arg_regs);
1601 			return true;
1602 		}
1603 
1604 		start = (unsigned long)state->stack;
1605 		end = (unsigned long)(state->stack + nslots);
1606 		if (nslots && addr >= start && addr < end) {
1607 			spi = ((const char *)reg - (const char *)state->stack) /
1608 			      sizeof(*state->stack);
1609 			*target = diag_stack_slot_target(state->diag_frame_id, state->frameno, spi);
1610 			return true;
1611 		}
1612 	}
1613 	return false;
1614 }
1615 
1616 void bpf_diag_mod_begin(struct bpf_verifier_env *env, const struct bpf_reg_state *reg,
1617 			const struct bpf_reg_state *origin, enum bpf_diag_mod_reason reason)
1618 {
1619 	struct bpf_diag *diag = env->diag;
1620 
1621 	if (!diag)
1622 		return;
1623 	diag->mod.active = reg_to_target(env, reg, &diag->mod.target);
1624 	if (!diag->mod.active)
1625 		return;
1626 	diag->mod.target_reg_snapshot = *reg;
1627 	diag->mod.insn_idx = env->insn_idx;
1628 	diag->mod.reason = reason;
1629 	diag->mod.origin_valid = origin && reg_to_target(env, origin, &diag->mod.origin);
1630 }
1631 
1632 void bpf_diag_mod_end(struct bpf_verifier_env *env)
1633 {
1634 	struct bpf_diag *diag = env->diag;
1635 	const struct bpf_reg_state *new_reg;
1636 
1637 	if (!diag || !diag->mod.active)
1638 		return;
1639 	diag->mod.active = false;
1640 	/*
1641 	 * Resolve the target again because the enclosing function state's stack
1642 	 * may have been reallocated while the modification was in progress.
1643 	 */
1644 	new_reg = target_to_reg(env, &diag->mod.target);
1645 	if (!new_reg)
1646 		return;
1647 	diag_record_mod(env, diag->mod.insn_idx, diag->mod.target, diag->mod.reason,
1648 			&diag->mod.target_reg_snapshot, new_reg,
1649 			diag->mod.origin_valid ? &diag->mod.origin : NULL);
1650 }
1651 
1652 void bpf_diag_record_scrub(struct bpf_verifier_env *env, const struct bpf_reg_state *reg,
1653 			   enum bpf_diag_mod_reason reason)
1654 {
1655 	struct bpf_diag_mod_target target;
1656 
1657 	if (!env->diag || reg->type == NOT_INIT || !reg_to_target(env, reg, &target))
1658 		return;
1659 	diag_record_mod(env, env->insn_idx, target, reason, reg, NULL, NULL);
1660 }
1661 
1662 void bpf_diag_record_scrub_stack(struct bpf_verifier_env *env,
1663 				 const struct bpf_func_state *state, s16 min_off, s16 max_off,
1664 				 enum bpf_diag_mod_reason reason)
1665 {
1666 	diag_record_mod(env, env->insn_idx,
1667 			diag_stack_range_target(state->diag_frame_id, state->frameno, min_off, max_off),
1668 			reason, NULL, NULL, NULL);
1669 }
1670 
1671 static void diag_record_ref(struct bpf_verifier_env *env, u32 insn_idx, u8 kind, u32 ref_id)
1672 {
1673 	struct bpf_diag_history_event event = {
1674 		.insn_idx = insn_idx,
1675 		.kind = kind,
1676 		.ref = {
1677 			.ref_id = ref_id,
1678 		},
1679 	};
1680 
1681 	diag_append_history(env, &event);
1682 }
1683 
1684 void bpf_diag_record_ref_acquire(struct bpf_verifier_env *env, u32 insn_idx, u32 ref_id)
1685 {
1686 	diag_record_ref(env, insn_idx, BPF_DIAG_HISTORY_REF_ACQUIRE, ref_id);
1687 }
1688 
1689 void bpf_diag_record_ref_release(struct bpf_verifier_env *env, u32 insn_idx, u32 ref_id)
1690 {
1691 	diag_record_ref(env, insn_idx, BPF_DIAG_HISTORY_REF_RELEASE, ref_id);
1692 }
1693 
1694 void bpf_diag_record_context(struct bpf_verifier_env *env, u32 insn_idx,
1695 			     enum bpf_diag_context_kind ctx_kind, bool enter, u32 depth)
1696 {
1697 	/*
1698 	 * Keep leave events so context rendering can stop at a depth-zero exit
1699 	 * and show nested-region depth accurately for the active path.
1700 	 */
1701 	struct bpf_diag_history_event event = {
1702 		.insn_idx = insn_idx,
1703 		.kind = BPF_DIAG_HISTORY_CONTEXT,
1704 		.ctx = {
1705 			.kind = ctx_kind,
1706 			.enter = enter,
1707 			.depth = depth,
1708 		},
1709 	};
1710 
1711 	diag_append_history(env, &event);
1712 }
1713 
1714 static int diag_history_context_start_idx(const struct bpf_diag_log *log,
1715 					  const struct bpf_diag_history_opts *opts)
1716 {
1717 	int i;
1718 
1719 	if (!opts->ctx_depth)
1720 		return 0;
1721 
1722 	/* Find the most recent outermost entry, or a depth-zero exit. */
1723 	for (i = log->cnt; i > 0; i--) {
1724 		const struct bpf_diag_history_event *event;
1725 
1726 		event = &log->events[log_pos(log, i - 1)];
1727 
1728 		if (event->kind != BPF_DIAG_HISTORY_CONTEXT || event->ctx.kind != opts->ctx_kind)
1729 			continue;
1730 
1731 		if (event->ctx.enter && event->ctx.depth == 1)
1732 			return i - 1;
1733 		if (!event->ctx.enter && event->ctx.depth == 0)
1734 			return 0;
1735 	}
1736 
1737 	return 0;
1738 }
1739 
1740 struct bpf_diag_history_filter {
1741 	const struct bpf_diag_history_opts *opts;
1742 	u32 lineage_start;
1743 	bool lineage_valid;
1744 };
1745 
1746 static bool diag_target_matches(const struct bpf_diag_mod_target *event_target,
1747 				const struct bpf_diag_mod_target *target)
1748 {
1749 	int slot_off;
1750 
1751 	if (event_target->frame_id != target->frame_id || event_target->frameno != target->frameno)
1752 		return false;
1753 
1754 	if (event_target->kind == BPF_DIAG_MOD_TARGET_STACK_RANGE &&
1755 	    target->kind == BPF_DIAG_MOD_TARGET_STACK_SLOT) {
1756 		slot_off = -(target->spi + 1) * BPF_REG_SIZE;
1757 		return event_target->range.min_off < slot_off + BPF_REG_SIZE &&
1758 		       event_target->range.max_off > slot_off;
1759 	}
1760 
1761 	if (event_target->kind != target->kind)
1762 		return false;
1763 
1764 	switch (target->kind) {
1765 	case BPF_DIAG_MOD_TARGET_REG:
1766 		return event_target->regno == target->regno;
1767 	case BPF_DIAG_MOD_TARGET_STACK_ARG:
1768 		return event_target->stack_arg == target->stack_arg;
1769 	case BPF_DIAG_MOD_TARGET_STACK_SLOT:
1770 		return event_target->spi == target->spi;
1771 	default:
1772 		return false;
1773 	}
1774 }
1775 
1776 static void diag_build_lineage(struct bpf_verifier_env *env, struct bpf_diag_log *log,
1777 			       struct bpf_diag_history_filter *filter)
1778 {
1779 	const struct bpf_diag_history_opts *opts = filter->opts;
1780 	struct bpf_diag_mod_target target;
1781 	int i;
1782 
1783 	for (i = 0; i < log->cnt; i++)
1784 		log->events[log_pos(log, i)].in_lineage = false;
1785 
1786 	if (opts->scope == BPF_DIAG_HISTORY_SCOPE_REG)
1787 		target = diag_reg_target(opts->frame_id, opts->frameno, opts->regno);
1788 	else if (opts->scope == BPF_DIAG_HISTORY_SCOPE_STACK_ARG)
1789 		target = diag_stack_arg_target(opts->frame_id, opts->frameno,
1790 					       opts->stack_arg_slot);
1791 	else
1792 		return;
1793 
1794 	/*
1795 	 * Find the nearest mutation of the active target. A fill or spill changes
1796 	 * the target to its origin, so the same walk follows register/stack
1797 	 * lineage recursively until it reaches the write that created the value.
1798 	 */
1799 	for (i = log->cnt; i > 0; i--) {
1800 		struct bpf_diag_history_event *event;
1801 
1802 		event = &log->events[log_pos(log, i - 1)];
1803 		if (event->kind != BPF_DIAG_HISTORY_MOD ||
1804 		    !diag_target_matches(&event->mod.target, &target))
1805 			continue;
1806 
1807 		event->in_lineage = true;
1808 		filter->lineage_start = i - 1;
1809 		filter->lineage_valid = true;
1810 
1811 		if (event->mod.origin_valid) {
1812 			target = event->mod.origin;
1813 			continue;
1814 		}
1815 		if (event->mod.reason != BPF_DIAG_MOD_WRITE &&
1816 		    event->mod.reason != BPF_DIAG_MOD_SPILL)
1817 			continue;
1818 		if (diag_mod_keeps_lineage(env, event))
1819 			continue;
1820 		break;
1821 	}
1822 }
1823 
1824 static int diag_history_start_idx(const struct bpf_diag_log *log,
1825 				  const struct bpf_diag_history_filter *filter)
1826 {
1827 	const struct bpf_diag_history_opts *opts = filter->opts;
1828 	int i;
1829 
1830 	if (opts->scope == BPF_DIAG_HISTORY_SCOPE_CONTEXT)
1831 		return diag_history_context_start_idx(log, opts);
1832 	if (filter->lineage_valid)
1833 		return filter->lineage_start;
1834 	if (opts->scope != BPF_DIAG_HISTORY_SCOPE_REF)
1835 		return 0;
1836 
1837 	for (i = log->cnt; i > 0; i--) {
1838 		const struct bpf_diag_history_event *event;
1839 
1840 		event = &log->events[log_pos(log, i - 1)];
1841 		if (event->kind == BPF_DIAG_HISTORY_REF_ACQUIRE &&
1842 		    event->ref.ref_id == opts->ref_id)
1843 			return i - 1;
1844 	}
1845 
1846 	return 0;
1847 }
1848 
1849 static bool diag_history_event_visible(const struct bpf_diag_history_event *event,
1850 				       const struct bpf_diag_history_filter *filter)
1851 {
1852 	const struct bpf_diag_history_opts *opts = filter->opts;
1853 
1854 	switch (event->kind) {
1855 	case BPF_DIAG_HISTORY_BRANCH:
1856 		return true;
1857 	case BPF_DIAG_HISTORY_MOD:
1858 		return filter->lineage_valid && event->in_lineage;
1859 	case BPF_DIAG_HISTORY_REF_ACQUIRE:
1860 	case BPF_DIAG_HISTORY_REF_RELEASE:
1861 		return opts->scope == BPF_DIAG_HISTORY_SCOPE_REF &&
1862 		       event->ref.ref_id == opts->ref_id;
1863 	case BPF_DIAG_HISTORY_CONTEXT:
1864 		return opts->scope == BPF_DIAG_HISTORY_SCOPE_CONTEXT &&
1865 		       event->ctx.kind == opts->ctx_kind;
1866 	default:
1867 		return false;
1868 	}
1869 }
1870 
1871 static const char *diag_s64_bound_name(s64 value)
1872 {
1873 	if (value == S64_MIN)
1874 		return "S64_MIN";
1875 	if (value == S64_MAX)
1876 		return "S64_MAX";
1877 	return NULL;
1878 }
1879 
1880 static const char *diag_u64_bound_name(u64 value)
1881 {
1882 	if (value == U64_MAX)
1883 		return "U64_MAX";
1884 	return NULL;
1885 }
1886 
1887 static const char *diag_s64_str(struct bpf_verifier_env *env, s64 value)
1888 {
1889 	return diag_s64_bound_name(value) ?: bpf_diag_fmt(env, "%lld", value);
1890 }
1891 
1892 static const char *diag_u64_str(struct bpf_verifier_env *env, u64 value)
1893 {
1894 	return diag_u64_bound_name(value) ?: bpf_diag_fmt(env, "%llu", value);
1895 }
1896 
1897 static bool diag_cnum64_unknown(struct cnum64 range)
1898 {
1899 	return cnum64_smin(range) == S64_MIN && cnum64_smax(range) == S64_MAX &&
1900 	       cnum64_umin(range) == 0 && cnum64_umax(range) == U64_MAX;
1901 }
1902 
1903 static bool diag_snapshot_unknown(const struct bpf_diag_reg_snapshot *snapshot)
1904 {
1905 	return tnum_is_unknown(snapshot->var_off) && diag_cnum64_unknown(snapshot->r64);
1906 }
1907 
1908 static const char *diag_scalar_range(struct bpf_verifier_env *env, struct cnum64 range)
1909 {
1910 	return bpf_diag_fmt(env, "signed range [%s, %s], unsigned range [%s, %s]",
1911 			    diag_s64_str(env, cnum64_smin(range)),
1912 			    diag_s64_str(env, cnum64_smax(range)),
1913 			    diag_u64_str(env, cnum64_umin(range)),
1914 			    diag_u64_str(env, cnum64_umax(range)));
1915 }
1916 
1917 const char *bpf_diag_fmt_s64_sum(struct bpf_verifier_env *env, s64 value, int addend)
1918 {
1919 	s64 sum;
1920 
1921 	if (check_add_overflow(value, (s64)addend, &sum))
1922 		return bpf_diag_fmt(env, "%lld plus %d (%s)", value, addend,
1923 				    addend < 0 ? "below S64_MIN" : "above S64_MAX");
1924 
1925 	return bpf_diag_fmt(env, "%lld", sum);
1926 }
1927 
1928 static const char *diag_access_offset(struct bpf_verifier_env *env, int off,
1929 				      const struct bpf_reg_state *reg)
1930 {
1931 	if (tnum_is_const(reg->var_off))
1932 		return bpf_diag_fmt(env, "constant %s",
1933 				    bpf_diag_fmt_s64_sum(env, (s64)reg->var_off.value, off));
1934 
1935 	if (tnum_is_unknown(reg->var_off) && diag_cnum64_unknown(reg->r64))
1936 		return bpf_diag_fmt(env, "unbounded");
1937 
1938 	if (off)
1939 		return bpf_diag_fmt(env,
1940 			"variable: known bits %#llx, unknown mask %#llx, plus fixed offset %d; %s",
1941 			(u64)reg->var_off.value, reg->var_off.mask, off,
1942 			diag_scalar_range(env, reg->r64));
1943 	return bpf_diag_fmt(env, "variable: known bits %#llx, unknown mask %#llx; %s",
1944 			    (u64)reg->var_off.value, reg->var_off.mask,
1945 			    diag_scalar_range(env, reg->r64));
1946 }
1947 
1948 void bpf_diag_mem_bounds(struct bpf_verifier_env *env, u32 insn_idx, int regno,
1949 			 const char *reg_name, const char *type_name, const char *proof,
1950 			 int off, int size, u32 mem_size, const struct bpf_reg_state *reg)
1951 {
1952 	const struct bpf_func_state *frame = diag_current_frame(env);
1953 	struct bpf_diag_history_opts opts = {
1954 		.scope = BPF_DIAG_HISTORY_SCOPE_REG,
1955 		.frame_id = frame->diag_frame_id,
1956 		.frameno = frame->frameno,
1957 		.regno = regno,
1958 	};
1959 	const char *offset_desc;
1960 
1961 	if (!bpf_diag_enabled(env))
1962 		return;
1963 
1964 	offset_desc = diag_access_offset(env, off, reg);
1965 
1966 	bpf_diag_header(env, MEMORY_SAFETY, "access outside bounds");
1967 	diag_reason(
1968 		env, "The verifier cannot prove offset + access_size <= object_size. Here, %s. %s is %s; offset is %s; access_size is %d; object_size is %u.",
1969 		proof, reg_name, type_name, offset_desc, size, mem_size);
1970 
1971 	diag_section(env, "At");
1972 	bpf_diag_source(env, insn_idx, "error", "access may be outside object bounds");
1973 
1974 	if (regno >= 0)
1975 		diag_print_history(env, &opts);
1976 
1977 	diag_suggestion(
1978 		env, "Add or adjust a bounds check that proves offset + access_size stays within the object.");
1979 }
1980 
1981 static const char *diag_lock_name(const struct bpf_reference_state *lock)
1982 {
1983 	switch (lock->type) {
1984 	case REF_TYPE_LOCK:
1985 		return "bpf_spin_lock";
1986 	case REF_TYPE_RES_LOCK:
1987 		return "resource spin lock";
1988 	case REF_TYPE_RES_LOCK_IRQ:
1989 		return "IRQ-saving resource spin lock";
1990 	default:
1991 		return "lock";
1992 	}
1993 }
1994 
1995 static void diag_res_report(struct bpf_verifier_env *env, u32 insn_idx, const char *problem,
1996 			    const char *reason)
1997 {
1998 	bpf_diag_header(env, RESOURCE_LIFETIME_SAFETY, problem);
1999 	diag_reason(env, "%s", reason);
2000 
2001 	diag_section(env, "At");
2002 	bpf_diag_source(env, insn_idx, "error", "%s", problem);
2003 }
2004 
2005 void bpf_diag_res(struct bpf_verifier_env *env, u32 insn_idx, const char *problem,
2006 		  const char *reason, const char *suggestion)
2007 {
2008 	diag_res_report(env, insn_idx, problem, reason);
2009 	diag_suggestion(env, "%s", suggestion);
2010 }
2011 
2012 void bpf_diag_lock(struct bpf_verifier_env *env, u32 insn_idx, const char *problem,
2013 		   const char *reason, const char *suggestion,
2014 		   const struct bpf_reference_state *active_lock)
2015 {
2016 	diag_res_report(env, insn_idx, problem, reason);
2017 
2018 	if (active_lock) {
2019 		diag_section(env, "Active lock");
2020 		bpf_diag_source(env, active_lock->insn_idx, "acquired",
2021 				"active %s has verifier identity %d",
2022 				diag_lock_name(active_lock), active_lock->id);
2023 	}
2024 
2025 	diag_suggestion(env, "%s", suggestion);
2026 }
2027 
2028 void bpf_diag_irq(struct bpf_verifier_env *env, u32 insn_idx, const char *problem,
2029 		  const char *reason, const char *suggestion, u32 depth)
2030 {
2031 	struct bpf_diag_history_opts opts = {
2032 		.scope = BPF_DIAG_HISTORY_SCOPE_CONTEXT,
2033 		.ctx_kind = BPF_DIAG_CONTEXT_IRQ,
2034 		.ctx_depth = depth,
2035 	};
2036 
2037 	bpf_diag_header(env, RESOURCE_LIFETIME_SAFETY, problem);
2038 	diag_reason(env, "%s", reason);
2039 
2040 	diag_section(env, "At");
2041 	bpf_diag_source(env, insn_idx, "error", "%s", problem);
2042 
2043 	if (depth)
2044 		diag_print_history(env, &opts);
2045 
2046 	diag_suggestion(env, "%s", suggestion);
2047 }
2048 
2049 void bpf_diag_leak(struct bpf_verifier_env *env, u32 ref_id, u32 alloc_insn, u32 fail_insn)
2050 {
2051 	struct bpf_diag_history_opts opts = {
2052 		.scope = BPF_DIAG_HISTORY_SCOPE_REF,
2053 		.ref_id = ref_id,
2054 	};
2055 
2056 	bpf_diag_header(env, RESOURCE_LIFETIME_SAFETY, "unreleased resource");
2057 	diag_reason(
2058 		env, "Owned resource (id=%u) was acquired at instruction %u and still needs to be released before this exit path.",
2059 		ref_id, alloc_insn);
2060 
2061 	diag_section(env, "At");
2062 	bpf_diag_source(env, fail_insn, "error",
2063 			"owned resource (id=%u) still needs release", ref_id);
2064 
2065 	diag_print_history(env, &opts);
2066 
2067 	diag_suggestion(
2068 		env, "Release or transfer ownership of the acquired resource on every path before the program exits.");
2069 }
2070 
2071 static const char *diag_var_offset(struct bpf_verifier_env *env,
2072 				   const struct bpf_diag_reg_snapshot *snapshot)
2073 {
2074 	if (tnum_is_const(snapshot->var_off))
2075 		return bpf_diag_fmt(env, "at offset %lld", (s64)snapshot->var_off.value);
2076 
2077 	if (diag_snapshot_unknown(snapshot))
2078 		return bpf_diag_fmt(env, "with unknown offset");
2079 
2080 	return bpf_diag_fmt(env,
2081 			    "with variable offset: known bits %#llx, unknown mask %#llx, %s",
2082 			    snapshot->var_off.value, snapshot->var_off.mask,
2083 			    diag_scalar_range(env, snapshot->r64));
2084 }
2085 
2086 static const char *diag_reg_map_name(const struct bpf_map *map)
2087 {
2088 	if (!map || !map->name[0])
2089 		return NULL;
2090 
2091 	return map->name;
2092 }
2093 
2094 static const char *diag_reg_snapshot(struct bpf_verifier_env *env,
2095 				     const struct bpf_diag_reg_snapshot *snapshot)
2096 {
2097 	const char *type_name = reg_type_str(env, snapshot->type);
2098 	const char *offset = diag_var_offset(env, snapshot);
2099 	const char *btf = snapshot->btf && snapshot->btf_id ?
2100 			  bpf_diag_fmt_btf_type(env, snapshot->btf, snapshot->btf_id) : NULL;
2101 	const char *map_name;
2102 
2103 	if (snapshot->type == SCALAR_VALUE) {
2104 		if (tnum_is_const(snapshot->var_off))
2105 			return bpf_diag_fmt(env, "integer scalar value %lld",
2106 					    (s64)snapshot->var_off.value);
2107 		if (diag_snapshot_unknown(snapshot))
2108 			return bpf_diag_fmt(env, "integer scalar with unknown value");
2109 		if (cnum64_is_const(snapshot->r64))
2110 			return bpf_diag_fmt(env, "integer scalar value %lld",
2111 					    cnum64_smin(snapshot->r64));
2112 		return bpf_diag_fmt(env, "integer scalar with %s",
2113 				    diag_scalar_range(env, snapshot->r64));
2114 	}
2115 
2116 	if (snapshot->type == NOT_INIT)
2117 		return bpf_diag_fmt(env, "uninitialized value");
2118 
2119 	if (base_type(snapshot->type) == PTR_TO_CTX)
2120 		return bpf_diag_fmt(env, "context pointer %s", offset);
2121 
2122 	if (base_type(snapshot->type) == PTR_TO_STACK)
2123 		return bpf_diag_fmt(env, "stack pointer %s", offset);
2124 
2125 	if (base_type(snapshot->type) == PTR_TO_MAP_VALUE) {
2126 		const char *kind = type_may_be_null(snapshot->type) ? "nullable map value" :
2127 								      "map value";
2128 
2129 		map_name = diag_reg_map_name(snapshot->map_ptr);
2130 		if (map_name)
2131 			return bpf_diag_fmt(env, "%s from %s %s", kind, map_name, offset);
2132 		return bpf_diag_fmt(env, "%s %s", kind, offset);
2133 	}
2134 
2135 	if (base_type(snapshot->type) == CONST_PTR_TO_MAP) {
2136 		map_name = diag_reg_map_name(snapshot->map_ptr);
2137 		if (map_name)
2138 			return bpf_diag_fmt(env, "map pointer for map %s", map_name);
2139 		return bpf_diag_fmt(env, "map pointer");
2140 	}
2141 
2142 	if (type_is_non_owning_ref(snapshot->type)) {
2143 		if (btf)
2144 			return bpf_diag_fmt(env, "borrowed allocated object pointer type=%s", btf);
2145 		return bpf_diag_fmt(env, "borrowed allocated object pointer");
2146 	}
2147 
2148 	if (type_is_ptr_alloc_obj(snapshot->type)) {
2149 		if (btf)
2150 			return bpf_diag_fmt(env, "owned allocated object pointer type=%s", btf);
2151 		return bpf_diag_fmt(env, "owned allocated object pointer");
2152 	}
2153 
2154 	if (base_type(snapshot->type) == PTR_TO_BTF_ID && btf)
2155 		return bpf_diag_fmt(env, "%s type=%s %s", type_name, btf, offset);
2156 
2157 	return bpf_diag_fmt(env, "%s %s", type_name, offset);
2158 }
2159 
2160 static const char *diag_mod_target_desc(struct bpf_verifier_env *env,
2161 					const struct bpf_diag_mod_target *target)
2162 {
2163 	switch (target->kind) {
2164 	case BPF_DIAG_MOD_TARGET_REG:
2165 		return bpf_diag_fmt(env, "R%u", target->regno);
2166 	case BPF_DIAG_MOD_TARGET_STACK_ARG:
2167 		return bpf_diag_fmt(env, "*(R11-%u)", (target->stack_arg + 1) * BPF_REG_SIZE);
2168 	case BPF_DIAG_MOD_TARGET_STACK_SLOT:
2169 		return bpf_diag_fmt(env, "stack slot fp%d", -(target->spi + 1) * BPF_REG_SIZE);
2170 	default:
2171 		return "value";
2172 	}
2173 }
2174 
2175 static void diag_print_mod(struct bpf_verifier_env *env, const struct bpf_diag_history_event *event)
2176 {
2177 	const struct bpf_diag_mod_target *target = &event->mod.target;
2178 	const char *target_desc, *reason = NULL, *old, *new;
2179 	const char *label = "update";
2180 
2181 	if (target->kind == BPF_DIAG_MOD_TARGET_STACK_RANGE) {
2182 		bpf_diag_source(
2183 			env, event->insn_idx, "invalidated",
2184 			"variable-offset stack write may affect bytes fp%d through fp%d",
2185 			target->range.min_off, target->range.max_off - 1);
2186 		return;
2187 	}
2188 
2189 	old = diag_reg_snapshot(env, &event->mod.old);
2190 	new = diag_reg_snapshot(env, &event->mod.new);
2191 	target_desc = diag_mod_target_desc(env, target);
2192 
2193 	switch (event->mod.reason) {
2194 	case BPF_DIAG_MOD_REF_RELEASE:
2195 		reason = target->kind == BPF_DIAG_MOD_TARGET_REG ? "resource release invalidated "
2196 								   "this pointer" :
2197 								   "resource release invalidated "
2198 								   "this value";
2199 		break;
2200 	case BPF_DIAG_MOD_PKT_DATA_CHANGE:
2201 		reason = "packet data may have moved";
2202 		break;
2203 	case BPF_DIAG_MOD_NON_OWN_REF:
2204 		reason = "leaving the protected region invalidated this borrowed pointer";
2205 		break;
2206 	case BPF_DIAG_MOD_CALLER_SAVED:
2207 		reason = target->kind == BPF_DIAG_MOD_TARGET_STACK_ARG ?
2208 			 "call invalidated this outgoing stack argument" :
2209 			 "call invalidated this caller-saved register";
2210 		break;
2211 	case BPF_DIAG_MOD_WRITE:
2212 		if (target->kind == BPF_DIAG_MOD_TARGET_STACK_SLOT)
2213 			reason = "a later stack write overwrote this spilled value";
2214 		break;
2215 	case BPF_DIAG_MOD_SPILL:
2216 		label = "spilled";
2217 		break;
2218 	case BPF_DIAG_MOD_VAR_WRITE:
2219 	default:
2220 		break;
2221 	}
2222 
2223 	if (reason) {
2224 		bpf_diag_source(env, event->insn_idx, "invalidated",
2225 				"%s: %s; previous value was %s", target_desc, reason, old);
2226 		return;
2227 	}
2228 
2229 	bpf_diag_source(env, event->insn_idx, label, "%s changed from %s to %s", target_desc,
2230 			old, new);
2231 }
2232 
2233 static void diag_print_ref_event(struct bpf_verifier_env *env,
2234 				 const struct bpf_diag_history_event *event)
2235 {
2236 	const char *label;
2237 
2238 	label = event->kind == BPF_DIAG_HISTORY_REF_ACQUIRE ? "acquired" : "released";
2239 	bpf_diag_source(env, event->insn_idx, label, "owned resource (id=%u)",
2240 			event->ref.ref_id);
2241 }
2242 
2243 static const char *diag_context_name(enum bpf_diag_context_kind kind)
2244 {
2245 	switch (kind) {
2246 	case BPF_DIAG_CONTEXT_RCU:
2247 		return "RCU read lock region";
2248 	case BPF_DIAG_CONTEXT_PREEMPT:
2249 		return "non-preemptible region";
2250 	case BPF_DIAG_CONTEXT_IRQ:
2251 		return "IRQ-disabled region";
2252 	case BPF_DIAG_CONTEXT_LOCK:
2253 		return "lock region";
2254 	case BPF_DIAG_CONTEXT_NONE:
2255 	default:
2256 		return "non-sleepable program";
2257 	}
2258 }
2259 
2260 static void diag_print_context_event(struct bpf_verifier_env *env,
2261 				     const struct bpf_diag_history_event *event)
2262 {
2263 	bpf_diag_source(env, event->insn_idx, "context", "%s %s; depth is now %u",
2264 			event->ctx.enter ? "entered" : "left",
2265 			diag_context_name(event->ctx.kind), event->ctx.depth);
2266 }
2267 
2268 static void diag_print_history(struct bpf_verifier_env *env,
2269 			       const struct bpf_diag_history_opts *opts)
2270 {
2271 	const struct bpf_diag_history_event *event;
2272 	struct bpf_diag_history_filter filter = {
2273 		.opts = opts,
2274 	};
2275 	struct bpf_diag_log *log;
2276 	struct diag_fmt_mark mark;
2277 	bool first = true;
2278 	int start_idx;
2279 	u32 i, visible_cnt = 0, visible_idx = 0;
2280 
2281 	if (!bpf_diag_enabled(env))
2282 		return;
2283 
2284 	if (!env->diag)
2285 		return;
2286 	log = &env->diag->log;
2287 
2288 	diag_build_lineage(env, log, &filter);
2289 
2290 	start_idx = diag_history_start_idx(log, &filter);
2291 	for (i = start_idx; i < log->cnt; i++) {
2292 		event = &log->events[log_pos(log, i)];
2293 		if (diag_history_event_visible(event, &filter))
2294 			visible_cnt++;
2295 	}
2296 
2297 	if (!visible_cnt && !log->first_seq && opts->scope == BPF_DIAG_HISTORY_SCOPE_STACK_ARG)
2298 		return;
2299 
2300 	diag_section(env, "Causal path");
2301 	mark = diag_fmt_save(env);
2302 	for (i = start_idx; i < log->cnt; i++) {
2303 		event = &log->events[log_pos(log, i)];
2304 		if (!diag_history_event_visible(event, &filter))
2305 			continue;
2306 
2307 		diag_fmt_restore(env, mark);
2308 		if (visible_cnt > BPF_DIAG_HISTORY_RENDER_MAX &&
2309 		    visible_idx >= BPF_DIAG_HISTORY_RENDER_MAX / 2 &&
2310 		    visible_idx < visible_cnt - BPF_DIAG_HISTORY_RENDER_MAX / 2) {
2311 			if (visible_idx++ != BPF_DIAG_HISTORY_RENDER_MAX / 2)
2312 				continue;
2313 			if (!first)
2314 				diag_write(env, "\n");
2315 			first = false;
2316 			diag_write(env, "  %u intermediate causal-history events omitted\n",
2317 				   visible_cnt - BPF_DIAG_HISTORY_RENDER_MAX);
2318 			continue;
2319 		}
2320 		visible_idx++;
2321 
2322 		if (!first)
2323 			diag_write(env, "\n");
2324 		first = false;
2325 
2326 		switch (event->kind) {
2327 		case BPF_DIAG_HISTORY_BRANCH:
2328 			bpf_diag_source(env, event->insn_idx, "branch",
2329 					"took the %s branch of this conditional, goto %s",
2330 					event->branch.cond_true ? "true" : "false",
2331 					event->branch.cond_true ? "followed" : "not followed");
2332 			break;
2333 		case BPF_DIAG_HISTORY_MOD:
2334 			diag_print_mod(env, event);
2335 			break;
2336 		case BPF_DIAG_HISTORY_REF_ACQUIRE:
2337 		case BPF_DIAG_HISTORY_REF_RELEASE:
2338 			diag_print_ref_event(env, event);
2339 			break;
2340 		case BPF_DIAG_HISTORY_CONTEXT:
2341 			diag_print_context_event(env, event);
2342 			break;
2343 		default:
2344 			break;
2345 		}
2346 	}
2347 
2348 	if (!visible_cnt)
2349 		diag_write(env, "  no retained diagnostic events on this path\n");
2350 	if (log->first_seq)
2351 		diag_write(env, "  %llu older causal-history event%s not retained because diagnostic "
2352 			   "event storage reached capacity\n",
2353 			   log->first_seq, log->first_seq == 1 ? "" : "s");
2354 	diag_fmt_restore(env, mark);
2355 }
2356