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