1 /* 2 * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com> 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 /* 19 * objtool check: 20 * 21 * This command analyzes every .o file and ensures the validity of its stack 22 * trace metadata. It enforces a set of rules on asm code and C inline 23 * assembly code so that stack traces can be reliable. 24 * 25 * For more information, see tools/objtool/Documentation/stack-validation.txt. 26 */ 27 28 #include <string.h> 29 #include <subcmd/parse-options.h> 30 31 #include "builtin.h" 32 #include "elf.h" 33 #include "special.h" 34 #include "arch.h" 35 #include "warn.h" 36 37 #include <linux/hashtable.h> 38 39 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 40 41 #define STATE_FP_SAVED 0x1 42 #define STATE_FP_SETUP 0x2 43 #define STATE_FENTRY 0x4 44 45 struct instruction { 46 struct list_head list; 47 struct hlist_node hash; 48 struct section *sec; 49 unsigned long offset; 50 unsigned int len, state; 51 unsigned char type; 52 unsigned long immediate; 53 bool alt_group, visited; 54 struct symbol *call_dest; 55 struct instruction *jump_dest; 56 struct list_head alts; 57 struct symbol *func; 58 }; 59 60 struct alternative { 61 struct list_head list; 62 struct instruction *insn; 63 }; 64 65 struct objtool_file { 66 struct elf *elf; 67 struct list_head insn_list; 68 DECLARE_HASHTABLE(insn_hash, 16); 69 struct section *rodata, *whitelist; 70 bool ignore_unreachables, c_file; 71 }; 72 73 const char *objname; 74 static bool nofp; 75 76 static struct instruction *find_insn(struct objtool_file *file, 77 struct section *sec, unsigned long offset) 78 { 79 struct instruction *insn; 80 81 hash_for_each_possible(file->insn_hash, insn, hash, offset) 82 if (insn->sec == sec && insn->offset == offset) 83 return insn; 84 85 return NULL; 86 } 87 88 static struct instruction *next_insn_same_sec(struct objtool_file *file, 89 struct instruction *insn) 90 { 91 struct instruction *next = list_next_entry(insn, list); 92 93 if (&next->list == &file->insn_list || next->sec != insn->sec) 94 return NULL; 95 96 return next; 97 } 98 99 #define for_each_insn(file, insn) \ 100 list_for_each_entry(insn, &file->insn_list, list) 101 102 #define func_for_each_insn(file, func, insn) \ 103 for (insn = find_insn(file, func->sec, func->offset); \ 104 insn && &insn->list != &file->insn_list && \ 105 insn->sec == func->sec && \ 106 insn->offset < func->offset + func->len; \ 107 insn = list_next_entry(insn, list)) 108 109 #define sec_for_each_insn_from(file, insn) \ 110 for (; insn; insn = next_insn_same_sec(file, insn)) 111 112 113 /* 114 * Check if the function has been manually whitelisted with the 115 * STACK_FRAME_NON_STANDARD macro, or if it should be automatically whitelisted 116 * due to its use of a context switching instruction. 117 */ 118 static bool ignore_func(struct objtool_file *file, struct symbol *func) 119 { 120 struct rela *rela; 121 struct instruction *insn; 122 123 /* check for STACK_FRAME_NON_STANDARD */ 124 if (file->whitelist && file->whitelist->rela) 125 list_for_each_entry(rela, &file->whitelist->rela->rela_list, list) 126 if (rela->sym->sec == func->sec && 127 rela->addend == func->offset) 128 return true; 129 130 /* check if it has a context switching instruction */ 131 func_for_each_insn(file, func, insn) 132 if (insn->type == INSN_CONTEXT_SWITCH) 133 return true; 134 135 return false; 136 } 137 138 /* 139 * This checks to see if the given function is a "noreturn" function. 140 * 141 * For global functions which are outside the scope of this object file, we 142 * have to keep a manual list of them. 143 * 144 * For local functions, we have to detect them manually by simply looking for 145 * the lack of a return instruction. 146 * 147 * Returns: 148 * -1: error 149 * 0: no dead end 150 * 1: dead end 151 */ 152 static int __dead_end_function(struct objtool_file *file, struct symbol *func, 153 int recursion) 154 { 155 int i; 156 struct instruction *insn; 157 bool empty = true; 158 159 /* 160 * Unfortunately these have to be hard coded because the noreturn 161 * attribute isn't provided in ELF data. 162 */ 163 static const char * const global_noreturns[] = { 164 "__stack_chk_fail", 165 "panic", 166 "do_exit", 167 "__module_put_and_exit", 168 "complete_and_exit", 169 "kvm_spurious_fault", 170 "__reiserfs_panic", 171 "lbug_with_loc" 172 }; 173 174 if (func->bind == STB_WEAK) 175 return 0; 176 177 if (func->bind == STB_GLOBAL) 178 for (i = 0; i < ARRAY_SIZE(global_noreturns); i++) 179 if (!strcmp(func->name, global_noreturns[i])) 180 return 1; 181 182 if (!func->sec) 183 return 0; 184 185 func_for_each_insn(file, func, insn) { 186 empty = false; 187 188 if (insn->type == INSN_RETURN) 189 return 0; 190 } 191 192 if (empty) 193 return 0; 194 195 /* 196 * A function can have a sibling call instead of a return. In that 197 * case, the function's dead-end status depends on whether the target 198 * of the sibling call returns. 199 */ 200 func_for_each_insn(file, func, insn) { 201 if (insn->sec != func->sec || 202 insn->offset >= func->offset + func->len) 203 break; 204 205 if (insn->type == INSN_JUMP_UNCONDITIONAL) { 206 struct instruction *dest = insn->jump_dest; 207 struct symbol *dest_func; 208 209 if (!dest) 210 /* sibling call to another file */ 211 return 0; 212 213 if (dest->sec != func->sec || 214 dest->offset < func->offset || 215 dest->offset >= func->offset + func->len) { 216 /* local sibling call */ 217 dest_func = find_symbol_by_offset(dest->sec, 218 dest->offset); 219 if (!dest_func) 220 continue; 221 222 if (recursion == 5) { 223 WARN_FUNC("infinite recursion (objtool bug!)", 224 dest->sec, dest->offset); 225 return -1; 226 } 227 228 return __dead_end_function(file, dest_func, 229 recursion + 1); 230 } 231 } 232 233 if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts)) 234 /* sibling call */ 235 return 0; 236 } 237 238 return 1; 239 } 240 241 static int dead_end_function(struct objtool_file *file, struct symbol *func) 242 { 243 return __dead_end_function(file, func, 0); 244 } 245 246 /* 247 * Call the arch-specific instruction decoder for all the instructions and add 248 * them to the global instruction list. 249 */ 250 static int decode_instructions(struct objtool_file *file) 251 { 252 struct section *sec; 253 struct symbol *func; 254 unsigned long offset; 255 struct instruction *insn; 256 int ret; 257 258 list_for_each_entry(sec, &file->elf->sections, list) { 259 260 if (!(sec->sh.sh_flags & SHF_EXECINSTR)) 261 continue; 262 263 for (offset = 0; offset < sec->len; offset += insn->len) { 264 insn = malloc(sizeof(*insn)); 265 memset(insn, 0, sizeof(*insn)); 266 267 INIT_LIST_HEAD(&insn->alts); 268 insn->sec = sec; 269 insn->offset = offset; 270 271 ret = arch_decode_instruction(file->elf, sec, offset, 272 sec->len - offset, 273 &insn->len, &insn->type, 274 &insn->immediate); 275 if (ret) 276 return ret; 277 278 if (!insn->type || insn->type > INSN_LAST) { 279 WARN_FUNC("invalid instruction type %d", 280 insn->sec, insn->offset, insn->type); 281 return -1; 282 } 283 284 hash_add(file->insn_hash, &insn->hash, insn->offset); 285 list_add_tail(&insn->list, &file->insn_list); 286 } 287 288 list_for_each_entry(func, &sec->symbol_list, list) { 289 if (func->type != STT_FUNC) 290 continue; 291 292 if (!find_insn(file, sec, func->offset)) { 293 WARN("%s(): can't find starting instruction", 294 func->name); 295 return -1; 296 } 297 298 func_for_each_insn(file, func, insn) 299 if (!insn->func) 300 insn->func = func; 301 } 302 } 303 304 return 0; 305 } 306 307 /* 308 * Warnings shouldn't be reported for ignored functions. 309 */ 310 static void add_ignores(struct objtool_file *file) 311 { 312 struct instruction *insn; 313 struct section *sec; 314 struct symbol *func; 315 316 list_for_each_entry(sec, &file->elf->sections, list) { 317 list_for_each_entry(func, &sec->symbol_list, list) { 318 if (func->type != STT_FUNC) 319 continue; 320 321 if (!ignore_func(file, func)) 322 continue; 323 324 func_for_each_insn(file, func, insn) 325 insn->visited = true; 326 } 327 } 328 } 329 330 /* 331 * Find the destination instructions for all jumps. 332 */ 333 static int add_jump_destinations(struct objtool_file *file) 334 { 335 struct instruction *insn; 336 struct rela *rela; 337 struct section *dest_sec; 338 unsigned long dest_off; 339 340 for_each_insn(file, insn) { 341 if (insn->type != INSN_JUMP_CONDITIONAL && 342 insn->type != INSN_JUMP_UNCONDITIONAL) 343 continue; 344 345 /* skip ignores */ 346 if (insn->visited) 347 continue; 348 349 rela = find_rela_by_dest_range(insn->sec, insn->offset, 350 insn->len); 351 if (!rela) { 352 dest_sec = insn->sec; 353 dest_off = insn->offset + insn->len + insn->immediate; 354 } else if (rela->sym->type == STT_SECTION) { 355 dest_sec = rela->sym->sec; 356 dest_off = rela->addend + 4; 357 } else if (rela->sym->sec->idx) { 358 dest_sec = rela->sym->sec; 359 dest_off = rela->sym->sym.st_value + rela->addend + 4; 360 } else { 361 /* sibling call */ 362 insn->jump_dest = 0; 363 continue; 364 } 365 366 insn->jump_dest = find_insn(file, dest_sec, dest_off); 367 if (!insn->jump_dest) { 368 369 /* 370 * This is a special case where an alt instruction 371 * jumps past the end of the section. These are 372 * handled later in handle_group_alt(). 373 */ 374 if (!strcmp(insn->sec->name, ".altinstr_replacement")) 375 continue; 376 377 WARN_FUNC("can't find jump dest instruction at %s+0x%lx", 378 insn->sec, insn->offset, dest_sec->name, 379 dest_off); 380 return -1; 381 } 382 } 383 384 return 0; 385 } 386 387 /* 388 * Find the destination instructions for all calls. 389 */ 390 static int add_call_destinations(struct objtool_file *file) 391 { 392 struct instruction *insn; 393 unsigned long dest_off; 394 struct rela *rela; 395 396 for_each_insn(file, insn) { 397 if (insn->type != INSN_CALL) 398 continue; 399 400 rela = find_rela_by_dest_range(insn->sec, insn->offset, 401 insn->len); 402 if (!rela) { 403 dest_off = insn->offset + insn->len + insn->immediate; 404 insn->call_dest = find_symbol_by_offset(insn->sec, 405 dest_off); 406 if (!insn->call_dest) { 407 WARN_FUNC("can't find call dest symbol at offset 0x%lx", 408 insn->sec, insn->offset, dest_off); 409 return -1; 410 } 411 } else if (rela->sym->type == STT_SECTION) { 412 insn->call_dest = find_symbol_by_offset(rela->sym->sec, 413 rela->addend+4); 414 if (!insn->call_dest || 415 insn->call_dest->type != STT_FUNC) { 416 WARN_FUNC("can't find call dest symbol at %s+0x%x", 417 insn->sec, insn->offset, 418 rela->sym->sec->name, 419 rela->addend + 4); 420 return -1; 421 } 422 } else 423 insn->call_dest = rela->sym; 424 } 425 426 return 0; 427 } 428 429 /* 430 * The .alternatives section requires some extra special care, over and above 431 * what other special sections require: 432 * 433 * 1. Because alternatives are patched in-place, we need to insert a fake jump 434 * instruction at the end so that validate_branch() skips all the original 435 * replaced instructions when validating the new instruction path. 436 * 437 * 2. An added wrinkle is that the new instruction length might be zero. In 438 * that case the old instructions are replaced with noops. We simulate that 439 * by creating a fake jump as the only new instruction. 440 * 441 * 3. In some cases, the alternative section includes an instruction which 442 * conditionally jumps to the _end_ of the entry. We have to modify these 443 * jumps' destinations to point back to .text rather than the end of the 444 * entry in .altinstr_replacement. 445 * 446 * 4. It has been requested that we don't validate the !POPCNT feature path 447 * which is a "very very small percentage of machines". 448 */ 449 static int handle_group_alt(struct objtool_file *file, 450 struct special_alt *special_alt, 451 struct instruction *orig_insn, 452 struct instruction **new_insn) 453 { 454 struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump; 455 unsigned long dest_off; 456 457 last_orig_insn = NULL; 458 insn = orig_insn; 459 sec_for_each_insn_from(file, insn) { 460 if (insn->offset >= special_alt->orig_off + special_alt->orig_len) 461 break; 462 463 if (special_alt->skip_orig) 464 insn->type = INSN_NOP; 465 466 insn->alt_group = true; 467 last_orig_insn = insn; 468 } 469 470 if (!next_insn_same_sec(file, last_orig_insn)) { 471 WARN("%s: don't know how to handle alternatives at end of section", 472 special_alt->orig_sec->name); 473 return -1; 474 } 475 476 fake_jump = malloc(sizeof(*fake_jump)); 477 if (!fake_jump) { 478 WARN("malloc failed"); 479 return -1; 480 } 481 memset(fake_jump, 0, sizeof(*fake_jump)); 482 INIT_LIST_HEAD(&fake_jump->alts); 483 fake_jump->sec = special_alt->new_sec; 484 fake_jump->offset = -1; 485 fake_jump->type = INSN_JUMP_UNCONDITIONAL; 486 fake_jump->jump_dest = list_next_entry(last_orig_insn, list); 487 488 if (!special_alt->new_len) { 489 *new_insn = fake_jump; 490 return 0; 491 } 492 493 last_new_insn = NULL; 494 insn = *new_insn; 495 sec_for_each_insn_from(file, insn) { 496 if (insn->offset >= special_alt->new_off + special_alt->new_len) 497 break; 498 499 last_new_insn = insn; 500 501 if (insn->type != INSN_JUMP_CONDITIONAL && 502 insn->type != INSN_JUMP_UNCONDITIONAL) 503 continue; 504 505 if (!insn->immediate) 506 continue; 507 508 dest_off = insn->offset + insn->len + insn->immediate; 509 if (dest_off == special_alt->new_off + special_alt->new_len) 510 insn->jump_dest = fake_jump; 511 512 if (!insn->jump_dest) { 513 WARN_FUNC("can't find alternative jump destination", 514 insn->sec, insn->offset); 515 return -1; 516 } 517 } 518 519 if (!last_new_insn) { 520 WARN_FUNC("can't find last new alternative instruction", 521 special_alt->new_sec, special_alt->new_off); 522 return -1; 523 } 524 525 list_add(&fake_jump->list, &last_new_insn->list); 526 527 return 0; 528 } 529 530 /* 531 * A jump table entry can either convert a nop to a jump or a jump to a nop. 532 * If the original instruction is a jump, make the alt entry an effective nop 533 * by just skipping the original instruction. 534 */ 535 static int handle_jump_alt(struct objtool_file *file, 536 struct special_alt *special_alt, 537 struct instruction *orig_insn, 538 struct instruction **new_insn) 539 { 540 if (orig_insn->type == INSN_NOP) 541 return 0; 542 543 if (orig_insn->type != INSN_JUMP_UNCONDITIONAL) { 544 WARN_FUNC("unsupported instruction at jump label", 545 orig_insn->sec, orig_insn->offset); 546 return -1; 547 } 548 549 *new_insn = list_next_entry(orig_insn, list); 550 return 0; 551 } 552 553 /* 554 * Read all the special sections which have alternate instructions which can be 555 * patched in or redirected to at runtime. Each instruction having alternate 556 * instruction(s) has them added to its insn->alts list, which will be 557 * traversed in validate_branch(). 558 */ 559 static int add_special_section_alts(struct objtool_file *file) 560 { 561 struct list_head special_alts; 562 struct instruction *orig_insn, *new_insn; 563 struct special_alt *special_alt, *tmp; 564 struct alternative *alt; 565 int ret; 566 567 ret = special_get_alts(file->elf, &special_alts); 568 if (ret) 569 return ret; 570 571 list_for_each_entry_safe(special_alt, tmp, &special_alts, list) { 572 alt = malloc(sizeof(*alt)); 573 if (!alt) { 574 WARN("malloc failed"); 575 ret = -1; 576 goto out; 577 } 578 579 orig_insn = find_insn(file, special_alt->orig_sec, 580 special_alt->orig_off); 581 if (!orig_insn) { 582 WARN_FUNC("special: can't find orig instruction", 583 special_alt->orig_sec, special_alt->orig_off); 584 ret = -1; 585 goto out; 586 } 587 588 new_insn = NULL; 589 if (!special_alt->group || special_alt->new_len) { 590 new_insn = find_insn(file, special_alt->new_sec, 591 special_alt->new_off); 592 if (!new_insn) { 593 WARN_FUNC("special: can't find new instruction", 594 special_alt->new_sec, 595 special_alt->new_off); 596 ret = -1; 597 goto out; 598 } 599 } 600 601 if (special_alt->group) { 602 ret = handle_group_alt(file, special_alt, orig_insn, 603 &new_insn); 604 if (ret) 605 goto out; 606 } else if (special_alt->jump_or_nop) { 607 ret = handle_jump_alt(file, special_alt, orig_insn, 608 &new_insn); 609 if (ret) 610 goto out; 611 } 612 613 alt->insn = new_insn; 614 list_add_tail(&alt->list, &orig_insn->alts); 615 616 list_del(&special_alt->list); 617 free(special_alt); 618 } 619 620 out: 621 return ret; 622 } 623 624 static int add_switch_table(struct objtool_file *file, struct symbol *func, 625 struct instruction *insn, struct rela *table, 626 struct rela *next_table) 627 { 628 struct rela *rela = table; 629 struct instruction *alt_insn; 630 struct alternative *alt; 631 632 list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) { 633 if (rela == next_table) 634 break; 635 636 if (rela->sym->sec != insn->sec || 637 rela->addend <= func->offset || 638 rela->addend >= func->offset + func->len) 639 break; 640 641 alt_insn = find_insn(file, insn->sec, rela->addend); 642 if (!alt_insn) { 643 WARN("%s: can't find instruction at %s+0x%x", 644 file->rodata->rela->name, insn->sec->name, 645 rela->addend); 646 return -1; 647 } 648 649 alt = malloc(sizeof(*alt)); 650 if (!alt) { 651 WARN("malloc failed"); 652 return -1; 653 } 654 655 alt->insn = alt_insn; 656 list_add_tail(&alt->list, &insn->alts); 657 } 658 659 return 0; 660 } 661 662 static int add_func_switch_tables(struct objtool_file *file, 663 struct symbol *func) 664 { 665 struct instruction *insn, *prev_jump; 666 struct rela *text_rela, *rodata_rela, *prev_rela; 667 int ret; 668 669 prev_jump = NULL; 670 671 func_for_each_insn(file, func, insn) { 672 if (insn->type != INSN_JUMP_DYNAMIC) 673 continue; 674 675 text_rela = find_rela_by_dest_range(insn->sec, insn->offset, 676 insn->len); 677 if (!text_rela || text_rela->sym != file->rodata->sym) 678 continue; 679 680 /* common case: jmpq *[addr](,%rax,8) */ 681 rodata_rela = find_rela_by_dest(file->rodata, 682 text_rela->addend); 683 684 /* 685 * rare case: jmpq *[addr](%rip) 686 * 687 * This check is for a rare gcc quirk, currently only seen in 688 * three driver functions in the kernel, only with certain 689 * obscure non-distro configs. 690 * 691 * As part of an optimization, gcc makes a copy of an existing 692 * switch jump table, modifies it, and then hard-codes the jump 693 * (albeit with an indirect jump) to use a single entry in the 694 * table. The rest of the jump table and some of its jump 695 * targets remain as dead code. 696 * 697 * In such a case we can just crudely ignore all unreachable 698 * instruction warnings for the entire object file. Ideally we 699 * would just ignore them for the function, but that would 700 * require redesigning the code quite a bit. And honestly 701 * that's just not worth doing: unreachable instruction 702 * warnings are of questionable value anyway, and this is such 703 * a rare issue. 704 * 705 * kbuild reports: 706 * - https://lkml.kernel.org/r/201603231906.LWcVUpxm%25fengguang.wu@intel.com 707 * - https://lkml.kernel.org/r/201603271114.K9i45biy%25fengguang.wu@intel.com 708 * - https://lkml.kernel.org/r/201603291058.zuJ6ben1%25fengguang.wu@intel.com 709 * 710 * gcc bug: 711 * - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70604 712 */ 713 if (!rodata_rela) { 714 rodata_rela = find_rela_by_dest(file->rodata, 715 text_rela->addend + 4); 716 if (rodata_rela) 717 file->ignore_unreachables = true; 718 } 719 720 if (!rodata_rela) 721 continue; 722 723 /* 724 * We found a switch table, but we don't know yet how big it 725 * is. Don't add it until we reach the end of the function or 726 * the beginning of another switch table in the same function. 727 */ 728 if (prev_jump) { 729 ret = add_switch_table(file, func, prev_jump, prev_rela, 730 rodata_rela); 731 if (ret) 732 return ret; 733 } 734 735 prev_jump = insn; 736 prev_rela = rodata_rela; 737 } 738 739 if (prev_jump) { 740 ret = add_switch_table(file, func, prev_jump, prev_rela, NULL); 741 if (ret) 742 return ret; 743 } 744 745 return 0; 746 } 747 748 /* 749 * For some switch statements, gcc generates a jump table in the .rodata 750 * section which contains a list of addresses within the function to jump to. 751 * This finds these jump tables and adds them to the insn->alts lists. 752 */ 753 static int add_switch_table_alts(struct objtool_file *file) 754 { 755 struct section *sec; 756 struct symbol *func; 757 int ret; 758 759 if (!file->rodata || !file->rodata->rela) 760 return 0; 761 762 list_for_each_entry(sec, &file->elf->sections, list) { 763 list_for_each_entry(func, &sec->symbol_list, list) { 764 if (func->type != STT_FUNC) 765 continue; 766 767 ret = add_func_switch_tables(file, func); 768 if (ret) 769 return ret; 770 } 771 } 772 773 return 0; 774 } 775 776 static int decode_sections(struct objtool_file *file) 777 { 778 int ret; 779 780 ret = decode_instructions(file); 781 if (ret) 782 return ret; 783 784 add_ignores(file); 785 786 ret = add_jump_destinations(file); 787 if (ret) 788 return ret; 789 790 ret = add_call_destinations(file); 791 if (ret) 792 return ret; 793 794 ret = add_special_section_alts(file); 795 if (ret) 796 return ret; 797 798 ret = add_switch_table_alts(file); 799 if (ret) 800 return ret; 801 802 return 0; 803 } 804 805 static bool is_fentry_call(struct instruction *insn) 806 { 807 if (insn->type == INSN_CALL && 808 insn->call_dest->type == STT_NOTYPE && 809 !strcmp(insn->call_dest->name, "__fentry__")) 810 return true; 811 812 return false; 813 } 814 815 static bool has_modified_stack_frame(struct instruction *insn) 816 { 817 return (insn->state & STATE_FP_SAVED) || 818 (insn->state & STATE_FP_SETUP); 819 } 820 821 static bool has_valid_stack_frame(struct instruction *insn) 822 { 823 return (insn->state & STATE_FP_SAVED) && 824 (insn->state & STATE_FP_SETUP); 825 } 826 827 static unsigned int frame_state(unsigned long state) 828 { 829 return (state & (STATE_FP_SAVED | STATE_FP_SETUP)); 830 } 831 832 /* 833 * Follow the branch starting at the given instruction, and recursively follow 834 * any other branches (jumps). Meanwhile, track the frame pointer state at 835 * each instruction and validate all the rules described in 836 * tools/objtool/Documentation/stack-validation.txt. 837 */ 838 static int validate_branch(struct objtool_file *file, 839 struct instruction *first, unsigned char first_state) 840 { 841 struct alternative *alt; 842 struct instruction *insn; 843 struct section *sec; 844 struct symbol *func = NULL; 845 unsigned char state; 846 int ret; 847 848 insn = first; 849 sec = insn->sec; 850 state = first_state; 851 852 if (insn->alt_group && list_empty(&insn->alts)) { 853 WARN_FUNC("don't know how to handle branch to middle of alternative instruction group", 854 sec, insn->offset); 855 return 1; 856 } 857 858 while (1) { 859 if (file->c_file && insn->func) { 860 if (func && func != insn->func) { 861 WARN("%s() falls through to next function %s()", 862 func->name, insn->func->name); 863 return 1; 864 } 865 866 func = insn->func; 867 } 868 869 if (insn->visited) { 870 if (frame_state(insn->state) != frame_state(state)) { 871 WARN_FUNC("frame pointer state mismatch", 872 sec, insn->offset); 873 return 1; 874 } 875 876 return 0; 877 } 878 879 insn->visited = true; 880 insn->state = state; 881 882 list_for_each_entry(alt, &insn->alts, list) { 883 ret = validate_branch(file, alt->insn, state); 884 if (ret) 885 return 1; 886 } 887 888 switch (insn->type) { 889 890 case INSN_FP_SAVE: 891 if (!nofp) { 892 if (state & STATE_FP_SAVED) { 893 WARN_FUNC("duplicate frame pointer save", 894 sec, insn->offset); 895 return 1; 896 } 897 state |= STATE_FP_SAVED; 898 } 899 break; 900 901 case INSN_FP_SETUP: 902 if (!nofp) { 903 if (state & STATE_FP_SETUP) { 904 WARN_FUNC("duplicate frame pointer setup", 905 sec, insn->offset); 906 return 1; 907 } 908 state |= STATE_FP_SETUP; 909 } 910 break; 911 912 case INSN_FP_RESTORE: 913 if (!nofp) { 914 if (has_valid_stack_frame(insn)) 915 state &= ~STATE_FP_SETUP; 916 917 state &= ~STATE_FP_SAVED; 918 } 919 break; 920 921 case INSN_RETURN: 922 if (!nofp && has_modified_stack_frame(insn)) { 923 WARN_FUNC("return without frame pointer restore", 924 sec, insn->offset); 925 return 1; 926 } 927 return 0; 928 929 case INSN_CALL: 930 if (is_fentry_call(insn)) { 931 state |= STATE_FENTRY; 932 break; 933 } 934 935 ret = dead_end_function(file, insn->call_dest); 936 if (ret == 1) 937 return 0; 938 if (ret == -1) 939 return 1; 940 941 /* fallthrough */ 942 case INSN_CALL_DYNAMIC: 943 if (!nofp && !has_valid_stack_frame(insn)) { 944 WARN_FUNC("call without frame pointer save/setup", 945 sec, insn->offset); 946 return 1; 947 } 948 break; 949 950 case INSN_JUMP_CONDITIONAL: 951 case INSN_JUMP_UNCONDITIONAL: 952 if (insn->jump_dest) { 953 ret = validate_branch(file, insn->jump_dest, 954 state); 955 if (ret) 956 return 1; 957 } else if (has_modified_stack_frame(insn)) { 958 WARN_FUNC("sibling call from callable instruction with changed frame pointer", 959 sec, insn->offset); 960 return 1; 961 } /* else it's a sibling call */ 962 963 if (insn->type == INSN_JUMP_UNCONDITIONAL) 964 return 0; 965 966 break; 967 968 case INSN_JUMP_DYNAMIC: 969 if (list_empty(&insn->alts) && 970 has_modified_stack_frame(insn)) { 971 WARN_FUNC("sibling call from callable instruction with changed frame pointer", 972 sec, insn->offset); 973 return 1; 974 } 975 976 return 0; 977 978 case INSN_BUG: 979 return 0; 980 981 default: 982 break; 983 } 984 985 insn = next_insn_same_sec(file, insn); 986 if (!insn) { 987 WARN("%s: unexpected end of section", sec->name); 988 return 1; 989 } 990 } 991 992 return 0; 993 } 994 995 static bool is_gcov_insn(struct instruction *insn) 996 { 997 struct rela *rela; 998 struct section *sec; 999 struct symbol *sym; 1000 unsigned long offset; 1001 1002 rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len); 1003 if (!rela) 1004 return false; 1005 1006 if (rela->sym->type != STT_SECTION) 1007 return false; 1008 1009 sec = rela->sym->sec; 1010 offset = rela->addend + insn->offset + insn->len - rela->offset; 1011 1012 list_for_each_entry(sym, &sec->symbol_list, list) { 1013 if (sym->type != STT_OBJECT) 1014 continue; 1015 1016 if (offset >= sym->offset && offset < sym->offset + sym->len) 1017 return (!memcmp(sym->name, "__gcov0.", 8)); 1018 } 1019 1020 return false; 1021 } 1022 1023 static bool is_kasan_insn(struct instruction *insn) 1024 { 1025 return (insn->type == INSN_CALL && 1026 !strcmp(insn->call_dest->name, "__asan_handle_no_return")); 1027 } 1028 1029 static bool is_ubsan_insn(struct instruction *insn) 1030 { 1031 return (insn->type == INSN_CALL && 1032 !strcmp(insn->call_dest->name, 1033 "__ubsan_handle_builtin_unreachable")); 1034 } 1035 1036 static bool ignore_unreachable_insn(struct symbol *func, 1037 struct instruction *insn) 1038 { 1039 int i; 1040 1041 if (insn->type == INSN_NOP) 1042 return true; 1043 1044 if (is_gcov_insn(insn)) 1045 return true; 1046 1047 /* 1048 * Check if this (or a subsequent) instruction is related to 1049 * CONFIG_UBSAN or CONFIG_KASAN. 1050 * 1051 * End the search at 5 instructions to avoid going into the weeds. 1052 */ 1053 for (i = 0; i < 5; i++) { 1054 1055 if (is_kasan_insn(insn) || is_ubsan_insn(insn)) 1056 return true; 1057 1058 if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest) { 1059 insn = insn->jump_dest; 1060 continue; 1061 } 1062 1063 if (insn->offset + insn->len >= func->offset + func->len) 1064 break; 1065 insn = list_next_entry(insn, list); 1066 } 1067 1068 return false; 1069 } 1070 1071 static int validate_functions(struct objtool_file *file) 1072 { 1073 struct section *sec; 1074 struct symbol *func; 1075 struct instruction *insn; 1076 int ret, warnings = 0; 1077 1078 list_for_each_entry(sec, &file->elf->sections, list) { 1079 list_for_each_entry(func, &sec->symbol_list, list) { 1080 if (func->type != STT_FUNC) 1081 continue; 1082 1083 insn = find_insn(file, sec, func->offset); 1084 if (!insn) 1085 continue; 1086 1087 ret = validate_branch(file, insn, 0); 1088 warnings += ret; 1089 } 1090 } 1091 1092 list_for_each_entry(sec, &file->elf->sections, list) { 1093 list_for_each_entry(func, &sec->symbol_list, list) { 1094 if (func->type != STT_FUNC) 1095 continue; 1096 1097 func_for_each_insn(file, func, insn) { 1098 if (insn->visited) 1099 continue; 1100 1101 insn->visited = true; 1102 1103 if (file->ignore_unreachables || warnings || 1104 ignore_unreachable_insn(func, insn)) 1105 continue; 1106 1107 WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset); 1108 warnings++; 1109 } 1110 } 1111 } 1112 1113 return warnings; 1114 } 1115 1116 static int validate_uncallable_instructions(struct objtool_file *file) 1117 { 1118 struct instruction *insn; 1119 int warnings = 0; 1120 1121 for_each_insn(file, insn) { 1122 if (!insn->visited && insn->type == INSN_RETURN) { 1123 WARN_FUNC("return instruction outside of a callable function", 1124 insn->sec, insn->offset); 1125 warnings++; 1126 } 1127 } 1128 1129 return warnings; 1130 } 1131 1132 static void cleanup(struct objtool_file *file) 1133 { 1134 struct instruction *insn, *tmpinsn; 1135 struct alternative *alt, *tmpalt; 1136 1137 list_for_each_entry_safe(insn, tmpinsn, &file->insn_list, list) { 1138 list_for_each_entry_safe(alt, tmpalt, &insn->alts, list) { 1139 list_del(&alt->list); 1140 free(alt); 1141 } 1142 list_del(&insn->list); 1143 hash_del(&insn->hash); 1144 free(insn); 1145 } 1146 elf_close(file->elf); 1147 } 1148 1149 const char * const check_usage[] = { 1150 "objtool check [<options>] file.o", 1151 NULL, 1152 }; 1153 1154 int cmd_check(int argc, const char **argv) 1155 { 1156 struct objtool_file file; 1157 int ret, warnings = 0; 1158 1159 const struct option options[] = { 1160 OPT_BOOLEAN('f', "no-fp", &nofp, "Skip frame pointer validation"), 1161 OPT_END(), 1162 }; 1163 1164 argc = parse_options(argc, argv, options, check_usage, 0); 1165 1166 if (argc != 1) 1167 usage_with_options(check_usage, options); 1168 1169 objname = argv[0]; 1170 1171 file.elf = elf_open(objname); 1172 if (!file.elf) { 1173 fprintf(stderr, "error reading elf file %s\n", objname); 1174 return 1; 1175 } 1176 1177 INIT_LIST_HEAD(&file.insn_list); 1178 hash_init(file.insn_hash); 1179 file.whitelist = find_section_by_name(file.elf, "__func_stack_frame_non_standard"); 1180 file.rodata = find_section_by_name(file.elf, ".rodata"); 1181 file.ignore_unreachables = false; 1182 file.c_file = find_section_by_name(file.elf, ".comment"); 1183 1184 ret = decode_sections(&file); 1185 if (ret < 0) 1186 goto out; 1187 warnings += ret; 1188 1189 ret = validate_functions(&file); 1190 if (ret < 0) 1191 goto out; 1192 warnings += ret; 1193 1194 ret = validate_uncallable_instructions(&file); 1195 if (ret < 0) 1196 goto out; 1197 warnings += ret; 1198 1199 out: 1200 cleanup(&file); 1201 1202 /* ignore warnings for now until we get all the code cleaned up */ 1203 if (ret || warnings) 1204 return 0; 1205 return 0; 1206 } 1207