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