1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * kallsyms.c: in-kernel printing of symbolic oopses and stack traces. 4 * 5 * Rewritten and vastly simplified by Rusty Russell for in-kernel 6 * module loader: 7 * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation 8 * 9 * ChangeLog: 10 * 11 * (25/Aug/2004) Paulo Marques <pmarques@grupopie.com> 12 * Changed the compression method from stem compression to "table lookup" 13 * compression (see scripts/kallsyms.c for a more complete description) 14 */ 15 #include <linux/kallsyms.h> 16 #include <linux/init.h> 17 #include <linux/seq_file.h> 18 #include <linux/fs.h> 19 #include <linux/kdb.h> 20 #include <linux/err.h> 21 #include <linux/proc_fs.h> 22 #include <linux/sched.h> /* for cond_resched */ 23 #include <linux/ctype.h> 24 #include <linux/slab.h> 25 #include <linux/filter.h> 26 #include <linux/ftrace.h> 27 #include <linux/kprobes.h> 28 #include <linux/build_bug.h> 29 #include <linux/compiler.h> 30 #include <linux/module.h> 31 #include <linux/kernel.h> 32 33 /* 34 * These will be re-linked against their real values 35 * during the second link stage. 36 */ 37 extern const unsigned long kallsyms_addresses[] __weak; 38 extern const int kallsyms_offsets[] __weak; 39 extern const u8 kallsyms_names[] __weak; 40 41 /* 42 * Tell the compiler that the count isn't in the small data section if the arch 43 * has one (eg: FRV). 44 */ 45 extern const unsigned int kallsyms_num_syms 46 __section(".rodata") __attribute__((weak)); 47 48 extern const unsigned long kallsyms_relative_base 49 __section(".rodata") __attribute__((weak)); 50 51 extern const char kallsyms_token_table[] __weak; 52 extern const u16 kallsyms_token_index[] __weak; 53 54 extern const unsigned int kallsyms_markers[] __weak; 55 56 /* 57 * Expand a compressed symbol data into the resulting uncompressed string, 58 * if uncompressed string is too long (>= maxlen), it will be truncated, 59 * given the offset to where the symbol is in the compressed stream. 60 */ 61 static unsigned int kallsyms_expand_symbol(unsigned int off, 62 char *result, size_t maxlen) 63 { 64 int len, skipped_first = 0; 65 const char *tptr; 66 const u8 *data; 67 68 /* Get the compressed symbol length from the first symbol byte. */ 69 data = &kallsyms_names[off]; 70 len = *data; 71 data++; 72 73 /* 74 * Update the offset to return the offset for the next symbol on 75 * the compressed stream. 76 */ 77 off += len + 1; 78 79 /* 80 * For every byte on the compressed symbol data, copy the table 81 * entry for that byte. 82 */ 83 while (len) { 84 tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; 85 data++; 86 len--; 87 88 while (*tptr) { 89 if (skipped_first) { 90 if (maxlen <= 1) 91 goto tail; 92 *result = *tptr; 93 result++; 94 maxlen--; 95 } else 96 skipped_first = 1; 97 tptr++; 98 } 99 } 100 101 tail: 102 if (maxlen) 103 *result = '\0'; 104 105 /* Return to offset to the next symbol. */ 106 return off; 107 } 108 109 /* 110 * Get symbol type information. This is encoded as a single char at the 111 * beginning of the symbol name. 112 */ 113 static char kallsyms_get_symbol_type(unsigned int off) 114 { 115 /* 116 * Get just the first code, look it up in the token table, 117 * and return the first char from this token. 118 */ 119 return kallsyms_token_table[kallsyms_token_index[kallsyms_names[off + 1]]]; 120 } 121 122 123 /* 124 * Find the offset on the compressed stream given and index in the 125 * kallsyms array. 126 */ 127 static unsigned int get_symbol_offset(unsigned long pos) 128 { 129 const u8 *name; 130 int i; 131 132 /* 133 * Use the closest marker we have. We have markers every 256 positions, 134 * so that should be close enough. 135 */ 136 name = &kallsyms_names[kallsyms_markers[pos >> 8]]; 137 138 /* 139 * Sequentially scan all the symbols up to the point we're searching 140 * for. Every symbol is stored in a [<len>][<len> bytes of data] format, 141 * so we just need to add the len to the current pointer for every 142 * symbol we wish to skip. 143 */ 144 for (i = 0; i < (pos & 0xFF); i++) 145 name = name + (*name) + 1; 146 147 return name - kallsyms_names; 148 } 149 150 static unsigned long kallsyms_sym_address(int idx) 151 { 152 if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE)) 153 return kallsyms_addresses[idx]; 154 155 /* values are unsigned offsets if --absolute-percpu is not in effect */ 156 if (!IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU)) 157 return kallsyms_relative_base + (u32)kallsyms_offsets[idx]; 158 159 /* ...otherwise, positive offsets are absolute values */ 160 if (kallsyms_offsets[idx] >= 0) 161 return kallsyms_offsets[idx]; 162 163 /* ...and negative offsets are relative to kallsyms_relative_base - 1 */ 164 return kallsyms_relative_base - 1 - kallsyms_offsets[idx]; 165 } 166 167 #if defined(CONFIG_CFI_CLANG) && defined(CONFIG_LTO_CLANG_THIN) 168 /* 169 * LLVM appends a hash to static function names when ThinLTO and CFI are 170 * both enabled, i.e. foo() becomes foo$707af9a22804d33c81801f27dcfe489b. 171 * This causes confusion and potentially breaks user space tools, so we 172 * strip the suffix from expanded symbol names. 173 */ 174 static inline bool cleanup_symbol_name(char *s) 175 { 176 char *res; 177 178 res = strrchr(s, '$'); 179 if (res) 180 *res = '\0'; 181 182 return res != NULL; 183 } 184 #else 185 static inline bool cleanup_symbol_name(char *s) { return false; } 186 #endif 187 188 /* Lookup the address for this symbol. Returns 0 if not found. */ 189 unsigned long kallsyms_lookup_name(const char *name) 190 { 191 char namebuf[KSYM_NAME_LEN]; 192 unsigned long i; 193 unsigned int off; 194 195 for (i = 0, off = 0; i < kallsyms_num_syms; i++) { 196 off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); 197 198 if (strcmp(namebuf, name) == 0) 199 return kallsyms_sym_address(i); 200 201 if (cleanup_symbol_name(namebuf) && strcmp(namebuf, name) == 0) 202 return kallsyms_sym_address(i); 203 } 204 return module_kallsyms_lookup_name(name); 205 } 206 207 #ifdef CONFIG_LIVEPATCH 208 /* 209 * Iterate over all symbols in vmlinux. For symbols from modules use 210 * module_kallsyms_on_each_symbol instead. 211 */ 212 int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, 213 unsigned long), 214 void *data) 215 { 216 char namebuf[KSYM_NAME_LEN]; 217 unsigned long i; 218 unsigned int off; 219 int ret; 220 221 for (i = 0, off = 0; i < kallsyms_num_syms; i++) { 222 off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); 223 ret = fn(data, namebuf, NULL, kallsyms_sym_address(i)); 224 if (ret != 0) 225 return ret; 226 } 227 return 0; 228 } 229 #endif /* CONFIG_LIVEPATCH */ 230 231 static unsigned long get_symbol_pos(unsigned long addr, 232 unsigned long *symbolsize, 233 unsigned long *offset) 234 { 235 unsigned long symbol_start = 0, symbol_end = 0; 236 unsigned long i, low, high, mid; 237 238 /* This kernel should never had been booted. */ 239 if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE)) 240 BUG_ON(!kallsyms_addresses); 241 else 242 BUG_ON(!kallsyms_offsets); 243 244 /* Do a binary search on the sorted kallsyms_addresses array. */ 245 low = 0; 246 high = kallsyms_num_syms; 247 248 while (high - low > 1) { 249 mid = low + (high - low) / 2; 250 if (kallsyms_sym_address(mid) <= addr) 251 low = mid; 252 else 253 high = mid; 254 } 255 256 /* 257 * Search for the first aliased symbol. Aliased 258 * symbols are symbols with the same address. 259 */ 260 while (low && kallsyms_sym_address(low-1) == kallsyms_sym_address(low)) 261 --low; 262 263 symbol_start = kallsyms_sym_address(low); 264 265 /* Search for next non-aliased symbol. */ 266 for (i = low + 1; i < kallsyms_num_syms; i++) { 267 if (kallsyms_sym_address(i) > symbol_start) { 268 symbol_end = kallsyms_sym_address(i); 269 break; 270 } 271 } 272 273 /* If we found no next symbol, we use the end of the section. */ 274 if (!symbol_end) { 275 if (is_kernel_inittext(addr)) 276 symbol_end = (unsigned long)_einittext; 277 else if (IS_ENABLED(CONFIG_KALLSYMS_ALL)) 278 symbol_end = (unsigned long)_end; 279 else 280 symbol_end = (unsigned long)_etext; 281 } 282 283 if (symbolsize) 284 *symbolsize = symbol_end - symbol_start; 285 if (offset) 286 *offset = addr - symbol_start; 287 288 return low; 289 } 290 291 /* 292 * Lookup an address but don't bother to find any names. 293 */ 294 int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, 295 unsigned long *offset) 296 { 297 char namebuf[KSYM_NAME_LEN]; 298 299 if (is_ksym_addr(addr)) { 300 get_symbol_pos(addr, symbolsize, offset); 301 return 1; 302 } 303 return !!module_address_lookup(addr, symbolsize, offset, NULL, NULL, namebuf) || 304 !!__bpf_address_lookup(addr, symbolsize, offset, namebuf); 305 } 306 307 static const char *kallsyms_lookup_buildid(unsigned long addr, 308 unsigned long *symbolsize, 309 unsigned long *offset, char **modname, 310 const unsigned char **modbuildid, char *namebuf) 311 { 312 const char *ret; 313 314 namebuf[KSYM_NAME_LEN - 1] = 0; 315 namebuf[0] = 0; 316 317 if (is_ksym_addr(addr)) { 318 unsigned long pos; 319 320 pos = get_symbol_pos(addr, symbolsize, offset); 321 /* Grab name */ 322 kallsyms_expand_symbol(get_symbol_offset(pos), 323 namebuf, KSYM_NAME_LEN); 324 if (modname) 325 *modname = NULL; 326 if (modbuildid) 327 *modbuildid = NULL; 328 329 ret = namebuf; 330 goto found; 331 } 332 333 /* See if it's in a module or a BPF JITed image. */ 334 ret = module_address_lookup(addr, symbolsize, offset, 335 modname, modbuildid, namebuf); 336 if (!ret) 337 ret = bpf_address_lookup(addr, symbolsize, 338 offset, modname, namebuf); 339 340 if (!ret) 341 ret = ftrace_mod_address_lookup(addr, symbolsize, 342 offset, modname, namebuf); 343 344 found: 345 cleanup_symbol_name(namebuf); 346 return ret; 347 } 348 349 /* 350 * Lookup an address 351 * - modname is set to NULL if it's in the kernel. 352 * - We guarantee that the returned name is valid until we reschedule even if. 353 * It resides in a module. 354 * - We also guarantee that modname will be valid until rescheduled. 355 */ 356 const char *kallsyms_lookup(unsigned long addr, 357 unsigned long *symbolsize, 358 unsigned long *offset, 359 char **modname, char *namebuf) 360 { 361 return kallsyms_lookup_buildid(addr, symbolsize, offset, modname, 362 NULL, namebuf); 363 } 364 365 int lookup_symbol_name(unsigned long addr, char *symname) 366 { 367 int res; 368 369 symname[0] = '\0'; 370 symname[KSYM_NAME_LEN - 1] = '\0'; 371 372 if (is_ksym_addr(addr)) { 373 unsigned long pos; 374 375 pos = get_symbol_pos(addr, NULL, NULL); 376 /* Grab name */ 377 kallsyms_expand_symbol(get_symbol_offset(pos), 378 symname, KSYM_NAME_LEN); 379 goto found; 380 } 381 /* See if it's in a module. */ 382 res = lookup_module_symbol_name(addr, symname); 383 if (res) 384 return res; 385 386 found: 387 cleanup_symbol_name(symname); 388 return 0; 389 } 390 391 int lookup_symbol_attrs(unsigned long addr, unsigned long *size, 392 unsigned long *offset, char *modname, char *name) 393 { 394 int res; 395 396 name[0] = '\0'; 397 name[KSYM_NAME_LEN - 1] = '\0'; 398 399 if (is_ksym_addr(addr)) { 400 unsigned long pos; 401 402 pos = get_symbol_pos(addr, size, offset); 403 /* Grab name */ 404 kallsyms_expand_symbol(get_symbol_offset(pos), 405 name, KSYM_NAME_LEN); 406 modname[0] = '\0'; 407 goto found; 408 } 409 /* See if it's in a module. */ 410 res = lookup_module_symbol_attrs(addr, size, offset, modname, name); 411 if (res) 412 return res; 413 414 found: 415 cleanup_symbol_name(name); 416 return 0; 417 } 418 419 /* Look up a kernel symbol and return it in a text buffer. */ 420 static int __sprint_symbol(char *buffer, unsigned long address, 421 int symbol_offset, int add_offset, int add_buildid) 422 { 423 char *modname; 424 const unsigned char *buildid; 425 const char *name; 426 unsigned long offset, size; 427 int len; 428 429 address += symbol_offset; 430 name = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid, 431 buffer); 432 if (!name) 433 return sprintf(buffer, "0x%lx", address - symbol_offset); 434 435 if (name != buffer) 436 strcpy(buffer, name); 437 len = strlen(buffer); 438 offset -= symbol_offset; 439 440 if (add_offset) 441 len += sprintf(buffer + len, "+%#lx/%#lx", offset, size); 442 443 if (modname) { 444 len += sprintf(buffer + len, " [%s", modname); 445 #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) 446 if (add_buildid && buildid) { 447 /* build ID should match length of sprintf */ 448 #if IS_ENABLED(CONFIG_MODULES) 449 static_assert(sizeof(typeof_member(struct module, build_id)) == 20); 450 #endif 451 len += sprintf(buffer + len, " %20phN", buildid); 452 } 453 #endif 454 len += sprintf(buffer + len, "]"); 455 } 456 457 return len; 458 } 459 460 /** 461 * sprint_symbol - Look up a kernel symbol and return it in a text buffer 462 * @buffer: buffer to be stored 463 * @address: address to lookup 464 * 465 * This function looks up a kernel symbol with @address and stores its name, 466 * offset, size and module name to @buffer if possible. If no symbol was found, 467 * just saves its @address as is. 468 * 469 * This function returns the number of bytes stored in @buffer. 470 */ 471 int sprint_symbol(char *buffer, unsigned long address) 472 { 473 return __sprint_symbol(buffer, address, 0, 1, 0); 474 } 475 EXPORT_SYMBOL_GPL(sprint_symbol); 476 477 /** 478 * sprint_symbol_build_id - Look up a kernel symbol and return it in a text buffer 479 * @buffer: buffer to be stored 480 * @address: address to lookup 481 * 482 * This function looks up a kernel symbol with @address and stores its name, 483 * offset, size, module name and module build ID to @buffer if possible. If no 484 * symbol was found, just saves its @address as is. 485 * 486 * This function returns the number of bytes stored in @buffer. 487 */ 488 int sprint_symbol_build_id(char *buffer, unsigned long address) 489 { 490 return __sprint_symbol(buffer, address, 0, 1, 1); 491 } 492 EXPORT_SYMBOL_GPL(sprint_symbol_build_id); 493 494 /** 495 * sprint_symbol_no_offset - Look up a kernel symbol and return it in a text buffer 496 * @buffer: buffer to be stored 497 * @address: address to lookup 498 * 499 * This function looks up a kernel symbol with @address and stores its name 500 * and module name to @buffer if possible. If no symbol was found, just saves 501 * its @address as is. 502 * 503 * This function returns the number of bytes stored in @buffer. 504 */ 505 int sprint_symbol_no_offset(char *buffer, unsigned long address) 506 { 507 return __sprint_symbol(buffer, address, 0, 0, 0); 508 } 509 EXPORT_SYMBOL_GPL(sprint_symbol_no_offset); 510 511 /** 512 * sprint_backtrace - Look up a backtrace symbol and return it in a text buffer 513 * @buffer: buffer to be stored 514 * @address: address to lookup 515 * 516 * This function is for stack backtrace and does the same thing as 517 * sprint_symbol() but with modified/decreased @address. If there is a 518 * tail-call to the function marked "noreturn", gcc optimized out code after 519 * the call so that the stack-saved return address could point outside of the 520 * caller. This function ensures that kallsyms will find the original caller 521 * by decreasing @address. 522 * 523 * This function returns the number of bytes stored in @buffer. 524 */ 525 int sprint_backtrace(char *buffer, unsigned long address) 526 { 527 return __sprint_symbol(buffer, address, -1, 1, 0); 528 } 529 530 /** 531 * sprint_backtrace_build_id - Look up a backtrace symbol and return it in a text buffer 532 * @buffer: buffer to be stored 533 * @address: address to lookup 534 * 535 * This function is for stack backtrace and does the same thing as 536 * sprint_symbol() but with modified/decreased @address. If there is a 537 * tail-call to the function marked "noreturn", gcc optimized out code after 538 * the call so that the stack-saved return address could point outside of the 539 * caller. This function ensures that kallsyms will find the original caller 540 * by decreasing @address. This function also appends the module build ID to 541 * the @buffer if @address is within a kernel module. 542 * 543 * This function returns the number of bytes stored in @buffer. 544 */ 545 int sprint_backtrace_build_id(char *buffer, unsigned long address) 546 { 547 return __sprint_symbol(buffer, address, -1, 1, 1); 548 } 549 550 /* To avoid using get_symbol_offset for every symbol, we carry prefix along. */ 551 struct kallsym_iter { 552 loff_t pos; 553 loff_t pos_arch_end; 554 loff_t pos_mod_end; 555 loff_t pos_ftrace_mod_end; 556 loff_t pos_bpf_end; 557 unsigned long value; 558 unsigned int nameoff; /* If iterating in core kernel symbols. */ 559 char type; 560 char name[KSYM_NAME_LEN]; 561 char module_name[MODULE_NAME_LEN]; 562 int exported; 563 int show_value; 564 }; 565 566 int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value, 567 char *type, char *name) 568 { 569 return -EINVAL; 570 } 571 572 static int get_ksymbol_arch(struct kallsym_iter *iter) 573 { 574 int ret = arch_get_kallsym(iter->pos - kallsyms_num_syms, 575 &iter->value, &iter->type, 576 iter->name); 577 578 if (ret < 0) { 579 iter->pos_arch_end = iter->pos; 580 return 0; 581 } 582 583 return 1; 584 } 585 586 static int get_ksymbol_mod(struct kallsym_iter *iter) 587 { 588 int ret = module_get_kallsym(iter->pos - iter->pos_arch_end, 589 &iter->value, &iter->type, 590 iter->name, iter->module_name, 591 &iter->exported); 592 if (ret < 0) { 593 iter->pos_mod_end = iter->pos; 594 return 0; 595 } 596 597 return 1; 598 } 599 600 /* 601 * ftrace_mod_get_kallsym() may also get symbols for pages allocated for ftrace 602 * purposes. In that case "__builtin__ftrace" is used as a module name, even 603 * though "__builtin__ftrace" is not a module. 604 */ 605 static int get_ksymbol_ftrace_mod(struct kallsym_iter *iter) 606 { 607 int ret = ftrace_mod_get_kallsym(iter->pos - iter->pos_mod_end, 608 &iter->value, &iter->type, 609 iter->name, iter->module_name, 610 &iter->exported); 611 if (ret < 0) { 612 iter->pos_ftrace_mod_end = iter->pos; 613 return 0; 614 } 615 616 return 1; 617 } 618 619 static int get_ksymbol_bpf(struct kallsym_iter *iter) 620 { 621 int ret; 622 623 strlcpy(iter->module_name, "bpf", MODULE_NAME_LEN); 624 iter->exported = 0; 625 ret = bpf_get_kallsym(iter->pos - iter->pos_ftrace_mod_end, 626 &iter->value, &iter->type, 627 iter->name); 628 if (ret < 0) { 629 iter->pos_bpf_end = iter->pos; 630 return 0; 631 } 632 633 return 1; 634 } 635 636 /* 637 * This uses "__builtin__kprobes" as a module name for symbols for pages 638 * allocated for kprobes' purposes, even though "__builtin__kprobes" is not a 639 * module. 640 */ 641 static int get_ksymbol_kprobe(struct kallsym_iter *iter) 642 { 643 strlcpy(iter->module_name, "__builtin__kprobes", MODULE_NAME_LEN); 644 iter->exported = 0; 645 return kprobe_get_kallsym(iter->pos - iter->pos_bpf_end, 646 &iter->value, &iter->type, 647 iter->name) < 0 ? 0 : 1; 648 } 649 650 /* Returns space to next name. */ 651 static unsigned long get_ksymbol_core(struct kallsym_iter *iter) 652 { 653 unsigned off = iter->nameoff; 654 655 iter->module_name[0] = '\0'; 656 iter->value = kallsyms_sym_address(iter->pos); 657 658 iter->type = kallsyms_get_symbol_type(off); 659 660 off = kallsyms_expand_symbol(off, iter->name, ARRAY_SIZE(iter->name)); 661 662 return off - iter->nameoff; 663 } 664 665 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos) 666 { 667 iter->name[0] = '\0'; 668 iter->nameoff = get_symbol_offset(new_pos); 669 iter->pos = new_pos; 670 if (new_pos == 0) { 671 iter->pos_arch_end = 0; 672 iter->pos_mod_end = 0; 673 iter->pos_ftrace_mod_end = 0; 674 iter->pos_bpf_end = 0; 675 } 676 } 677 678 /* 679 * The end position (last + 1) of each additional kallsyms section is recorded 680 * in iter->pos_..._end as each section is added, and so can be used to 681 * determine which get_ksymbol_...() function to call next. 682 */ 683 static int update_iter_mod(struct kallsym_iter *iter, loff_t pos) 684 { 685 iter->pos = pos; 686 687 if ((!iter->pos_arch_end || iter->pos_arch_end > pos) && 688 get_ksymbol_arch(iter)) 689 return 1; 690 691 if ((!iter->pos_mod_end || iter->pos_mod_end > pos) && 692 get_ksymbol_mod(iter)) 693 return 1; 694 695 if ((!iter->pos_ftrace_mod_end || iter->pos_ftrace_mod_end > pos) && 696 get_ksymbol_ftrace_mod(iter)) 697 return 1; 698 699 if ((!iter->pos_bpf_end || iter->pos_bpf_end > pos) && 700 get_ksymbol_bpf(iter)) 701 return 1; 702 703 return get_ksymbol_kprobe(iter); 704 } 705 706 /* Returns false if pos at or past end of file. */ 707 static int update_iter(struct kallsym_iter *iter, loff_t pos) 708 { 709 /* Module symbols can be accessed randomly. */ 710 if (pos >= kallsyms_num_syms) 711 return update_iter_mod(iter, pos); 712 713 /* If we're not on the desired position, reset to new position. */ 714 if (pos != iter->pos) 715 reset_iter(iter, pos); 716 717 iter->nameoff += get_ksymbol_core(iter); 718 iter->pos++; 719 720 return 1; 721 } 722 723 static void *s_next(struct seq_file *m, void *p, loff_t *pos) 724 { 725 (*pos)++; 726 727 if (!update_iter(m->private, *pos)) 728 return NULL; 729 return p; 730 } 731 732 static void *s_start(struct seq_file *m, loff_t *pos) 733 { 734 if (!update_iter(m->private, *pos)) 735 return NULL; 736 return m->private; 737 } 738 739 static void s_stop(struct seq_file *m, void *p) 740 { 741 } 742 743 static int s_show(struct seq_file *m, void *p) 744 { 745 void *value; 746 struct kallsym_iter *iter = m->private; 747 748 /* Some debugging symbols have no name. Ignore them. */ 749 if (!iter->name[0]) 750 return 0; 751 752 value = iter->show_value ? (void *)iter->value : NULL; 753 754 if (iter->module_name[0]) { 755 char type; 756 757 /* 758 * Label it "global" if it is exported, 759 * "local" if not exported. 760 */ 761 type = iter->exported ? toupper(iter->type) : 762 tolower(iter->type); 763 seq_printf(m, "%px %c %s\t[%s]\n", value, 764 type, iter->name, iter->module_name); 765 } else 766 seq_printf(m, "%px %c %s\n", value, 767 iter->type, iter->name); 768 return 0; 769 } 770 771 static const struct seq_operations kallsyms_op = { 772 .start = s_start, 773 .next = s_next, 774 .stop = s_stop, 775 .show = s_show 776 }; 777 778 static inline int kallsyms_for_perf(void) 779 { 780 #ifdef CONFIG_PERF_EVENTS 781 extern int sysctl_perf_event_paranoid; 782 if (sysctl_perf_event_paranoid <= 1) 783 return 1; 784 #endif 785 return 0; 786 } 787 788 /* 789 * We show kallsyms information even to normal users if we've enabled 790 * kernel profiling and are explicitly not paranoid (so kptr_restrict 791 * is clear, and sysctl_perf_event_paranoid isn't set). 792 * 793 * Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to 794 * block even that). 795 */ 796 bool kallsyms_show_value(const struct cred *cred) 797 { 798 switch (kptr_restrict) { 799 case 0: 800 if (kallsyms_for_perf()) 801 return true; 802 fallthrough; 803 case 1: 804 if (security_capable(cred, &init_user_ns, CAP_SYSLOG, 805 CAP_OPT_NOAUDIT) == 0) 806 return true; 807 fallthrough; 808 default: 809 return false; 810 } 811 } 812 813 static int kallsyms_open(struct inode *inode, struct file *file) 814 { 815 /* 816 * We keep iterator in m->private, since normal case is to 817 * s_start from where we left off, so we avoid doing 818 * using get_symbol_offset for every symbol. 819 */ 820 struct kallsym_iter *iter; 821 iter = __seq_open_private(file, &kallsyms_op, sizeof(*iter)); 822 if (!iter) 823 return -ENOMEM; 824 reset_iter(iter, 0); 825 826 /* 827 * Instead of checking this on every s_show() call, cache 828 * the result here at open time. 829 */ 830 iter->show_value = kallsyms_show_value(file->f_cred); 831 return 0; 832 } 833 834 #ifdef CONFIG_KGDB_KDB 835 const char *kdb_walk_kallsyms(loff_t *pos) 836 { 837 static struct kallsym_iter kdb_walk_kallsyms_iter; 838 if (*pos == 0) { 839 memset(&kdb_walk_kallsyms_iter, 0, 840 sizeof(kdb_walk_kallsyms_iter)); 841 reset_iter(&kdb_walk_kallsyms_iter, 0); 842 } 843 while (1) { 844 if (!update_iter(&kdb_walk_kallsyms_iter, *pos)) 845 return NULL; 846 ++*pos; 847 /* Some debugging symbols have no name. Ignore them. */ 848 if (kdb_walk_kallsyms_iter.name[0]) 849 return kdb_walk_kallsyms_iter.name; 850 } 851 } 852 #endif /* CONFIG_KGDB_KDB */ 853 854 static const struct proc_ops kallsyms_proc_ops = { 855 .proc_open = kallsyms_open, 856 .proc_read = seq_read, 857 .proc_lseek = seq_lseek, 858 .proc_release = seq_release_private, 859 }; 860 861 static int __init kallsyms_init(void) 862 { 863 proc_create("kallsyms", 0444, NULL, &kallsyms_proc_ops); 864 return 0; 865 } 866 device_initcall(kallsyms_init); 867