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