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