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