kallsyms.c (14327B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Module kallsyms support 4 * 5 * Copyright (C) 2010 Rusty Russell 6 */ 7 8#include <linux/module.h> 9#include <linux/kallsyms.h> 10#include <linux/buildid.h> 11#include <linux/bsearch.h> 12#include "internal.h" 13 14/* Lookup exported symbol in given range of kernel_symbols */ 15static const struct kernel_symbol *lookup_exported_symbol(const char *name, 16 const struct kernel_symbol *start, 17 const struct kernel_symbol *stop) 18{ 19 return bsearch(name, start, stop - start, 20 sizeof(struct kernel_symbol), cmp_name); 21} 22 23static int is_exported(const char *name, unsigned long value, 24 const struct module *mod) 25{ 26 const struct kernel_symbol *ks; 27 28 if (!mod) 29 ks = lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab); 30 else 31 ks = lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms); 32 33 return ks && kernel_symbol_value(ks) == value; 34} 35 36/* As per nm */ 37static char elf_type(const Elf_Sym *sym, const struct load_info *info) 38{ 39 const Elf_Shdr *sechdrs = info->sechdrs; 40 41 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) { 42 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT) 43 return 'v'; 44 else 45 return 'w'; 46 } 47 if (sym->st_shndx == SHN_UNDEF) 48 return 'U'; 49 if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu) 50 return 'a'; 51 if (sym->st_shndx >= SHN_LORESERVE) 52 return '?'; 53 if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR) 54 return 't'; 55 if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC && 56 sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) { 57 if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE)) 58 return 'r'; 59 else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL) 60 return 'g'; 61 else 62 return 'd'; 63 } 64 if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) { 65 if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL) 66 return 's'; 67 else 68 return 'b'; 69 } 70 if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name, 71 ".debug")) { 72 return 'n'; 73 } 74 return '?'; 75} 76 77static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, 78 unsigned int shnum, unsigned int pcpundx) 79{ 80 const Elf_Shdr *sec; 81 82 if (src->st_shndx == SHN_UNDEF || 83 src->st_shndx >= shnum || 84 !src->st_name) 85 return false; 86 87#ifdef CONFIG_KALLSYMS_ALL 88 if (src->st_shndx == pcpundx) 89 return true; 90#endif 91 92 sec = sechdrs + src->st_shndx; 93 if (!(sec->sh_flags & SHF_ALLOC) 94#ifndef CONFIG_KALLSYMS_ALL 95 || !(sec->sh_flags & SHF_EXECINSTR) 96#endif 97 || (sec->sh_entsize & INIT_OFFSET_MASK)) 98 return false; 99 100 return true; 101} 102 103/* 104 * We only allocate and copy the strings needed by the parts of symtab 105 * we keep. This is simple, but has the effect of making multiple 106 * copies of duplicates. We could be more sophisticated, see 107 * linux-kernel thread starting with 108 * <73defb5e4bca04a6431392cc341112b1@localhost>. 109 */ 110void layout_symtab(struct module *mod, struct load_info *info) 111{ 112 Elf_Shdr *symsect = info->sechdrs + info->index.sym; 113 Elf_Shdr *strsect = info->sechdrs + info->index.str; 114 const Elf_Sym *src; 115 unsigned int i, nsrc, ndst, strtab_size = 0; 116 117 /* Put symbol section at end of init part of module. */ 118 symsect->sh_flags |= SHF_ALLOC; 119 symsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, symsect, 120 info->index.sym) | INIT_OFFSET_MASK; 121 pr_debug("\t%s\n", info->secstrings + symsect->sh_name); 122 123 src = (void *)info->hdr + symsect->sh_offset; 124 nsrc = symsect->sh_size / sizeof(*src); 125 126 /* Compute total space required for the core symbols' strtab. */ 127 for (ndst = i = 0; i < nsrc; i++) { 128 if (i == 0 || is_livepatch_module(mod) || 129 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum, 130 info->index.pcpu)) { 131 strtab_size += strlen(&info->strtab[src[i].st_name]) + 1; 132 ndst++; 133 } 134 } 135 136 /* Append room for core symbols at end of core part. */ 137 info->symoffs = ALIGN(mod->data_layout.size, symsect->sh_addralign ?: 1); 138 info->stroffs = mod->data_layout.size = info->symoffs + ndst * sizeof(Elf_Sym); 139 mod->data_layout.size += strtab_size; 140 info->core_typeoffs = mod->data_layout.size; 141 mod->data_layout.size += ndst * sizeof(char); 142 mod->data_layout.size = strict_align(mod->data_layout.size); 143 144 /* Put string table section at end of init part of module. */ 145 strsect->sh_flags |= SHF_ALLOC; 146 strsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, strsect, 147 info->index.str) | INIT_OFFSET_MASK; 148 pr_debug("\t%s\n", info->secstrings + strsect->sh_name); 149 150 /* We'll tack temporary mod_kallsyms on the end. */ 151 mod->init_layout.size = ALIGN(mod->init_layout.size, 152 __alignof__(struct mod_kallsyms)); 153 info->mod_kallsyms_init_off = mod->init_layout.size; 154 mod->init_layout.size += sizeof(struct mod_kallsyms); 155 info->init_typeoffs = mod->init_layout.size; 156 mod->init_layout.size += nsrc * sizeof(char); 157 mod->init_layout.size = strict_align(mod->init_layout.size); 158} 159 160/* 161 * We use the full symtab and strtab which layout_symtab arranged to 162 * be appended to the init section. Later we switch to the cut-down 163 * core-only ones. 164 */ 165void add_kallsyms(struct module *mod, const struct load_info *info) 166{ 167 unsigned int i, ndst; 168 const Elf_Sym *src; 169 Elf_Sym *dst; 170 char *s; 171 Elf_Shdr *symsec = &info->sechdrs[info->index.sym]; 172 173 /* Set up to point into init section. */ 174 mod->kallsyms = (void __rcu *)mod->init_layout.base + 175 info->mod_kallsyms_init_off; 176 177 preempt_disable(); 178 /* The following is safe since this pointer cannot change */ 179 rcu_dereference_sched(mod->kallsyms)->symtab = (void *)symsec->sh_addr; 180 rcu_dereference_sched(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym); 181 /* Make sure we get permanent strtab: don't use info->strtab. */ 182 rcu_dereference_sched(mod->kallsyms)->strtab = 183 (void *)info->sechdrs[info->index.str].sh_addr; 184 rcu_dereference_sched(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs; 185 186 /* 187 * Now populate the cut down core kallsyms for after init 188 * and set types up while we still have access to sections. 189 */ 190 mod->core_kallsyms.symtab = dst = mod->data_layout.base + info->symoffs; 191 mod->core_kallsyms.strtab = s = mod->data_layout.base + info->stroffs; 192 mod->core_kallsyms.typetab = mod->data_layout.base + info->core_typeoffs; 193 src = rcu_dereference_sched(mod->kallsyms)->symtab; 194 for (ndst = i = 0; i < rcu_dereference_sched(mod->kallsyms)->num_symtab; i++) { 195 rcu_dereference_sched(mod->kallsyms)->typetab[i] = elf_type(src + i, info); 196 if (i == 0 || is_livepatch_module(mod) || 197 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum, 198 info->index.pcpu)) { 199 mod->core_kallsyms.typetab[ndst] = 200 rcu_dereference_sched(mod->kallsyms)->typetab[i]; 201 dst[ndst] = src[i]; 202 dst[ndst++].st_name = s - mod->core_kallsyms.strtab; 203 s += strscpy(s, 204 &rcu_dereference_sched(mod->kallsyms)->strtab[src[i].st_name], 205 KSYM_NAME_LEN) + 1; 206 } 207 } 208 preempt_enable(); 209 mod->core_kallsyms.num_symtab = ndst; 210} 211 212#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) 213void init_build_id(struct module *mod, const struct load_info *info) 214{ 215 const Elf_Shdr *sechdr; 216 unsigned int i; 217 218 for (i = 0; i < info->hdr->e_shnum; i++) { 219 sechdr = &info->sechdrs[i]; 220 if (!sect_empty(sechdr) && sechdr->sh_type == SHT_NOTE && 221 !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id, 222 sechdr->sh_size)) 223 break; 224 } 225} 226#else 227void init_build_id(struct module *mod, const struct load_info *info) 228{ 229} 230#endif 231 232/* 233 * This ignores the intensely annoying "mapping symbols" found 234 * in ARM ELF files: $a, $t and $d. 235 */ 236static inline int is_arm_mapping_symbol(const char *str) 237{ 238 if (str[0] == '.' && str[1] == 'L') 239 return true; 240 return str[0] == '$' && strchr("axtd", str[1]) && 241 (str[2] == '\0' || str[2] == '.'); 242} 243 244static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum) 245{ 246 return kallsyms->strtab + kallsyms->symtab[symnum].st_name; 247} 248 249/* 250 * Given a module and address, find the corresponding symbol and return its name 251 * while providing its size and offset if needed. 252 */ 253static const char *find_kallsyms_symbol(struct module *mod, 254 unsigned long addr, 255 unsigned long *size, 256 unsigned long *offset) 257{ 258 unsigned int i, best = 0; 259 unsigned long nextval, bestval; 260 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); 261 262 /* At worse, next value is at end of module */ 263 if (within_module_init(addr, mod)) 264 nextval = (unsigned long)mod->init_layout.base + mod->init_layout.text_size; 265 else 266 nextval = (unsigned long)mod->core_layout.base + mod->core_layout.text_size; 267 268 bestval = kallsyms_symbol_value(&kallsyms->symtab[best]); 269 270 /* 271 * Scan for closest preceding symbol, and next symbol. (ELF 272 * starts real symbols at 1). 273 */ 274 for (i = 1; i < kallsyms->num_symtab; i++) { 275 const Elf_Sym *sym = &kallsyms->symtab[i]; 276 unsigned long thisval = kallsyms_symbol_value(sym); 277 278 if (sym->st_shndx == SHN_UNDEF) 279 continue; 280 281 /* 282 * We ignore unnamed symbols: they're uninformative 283 * and inserted at a whim. 284 */ 285 if (*kallsyms_symbol_name(kallsyms, i) == '\0' || 286 is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) 287 continue; 288 289 if (thisval <= addr && thisval > bestval) { 290 best = i; 291 bestval = thisval; 292 } 293 if (thisval > addr && thisval < nextval) 294 nextval = thisval; 295 } 296 297 if (!best) 298 return NULL; 299 300 if (size) 301 *size = nextval - bestval; 302 if (offset) 303 *offset = addr - bestval; 304 305 return kallsyms_symbol_name(kallsyms, best); 306} 307 308void * __weak dereference_module_function_descriptor(struct module *mod, 309 void *ptr) 310{ 311 return ptr; 312} 313 314/* 315 * For kallsyms to ask for address resolution. NULL means not found. Careful 316 * not to lock to avoid deadlock on oopses, simply disable preemption. 317 */ 318const char *module_address_lookup(unsigned long addr, 319 unsigned long *size, 320 unsigned long *offset, 321 char **modname, 322 const unsigned char **modbuildid, 323 char *namebuf) 324{ 325 const char *ret = NULL; 326 struct module *mod; 327 328 preempt_disable(); 329 mod = __module_address(addr); 330 if (mod) { 331 if (modname) 332 *modname = mod->name; 333 if (modbuildid) { 334#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) 335 *modbuildid = mod->build_id; 336#else 337 *modbuildid = NULL; 338#endif 339 } 340 341 ret = find_kallsyms_symbol(mod, addr, size, offset); 342 } 343 /* Make a copy in here where it's safe */ 344 if (ret) { 345 strncpy(namebuf, ret, KSYM_NAME_LEN - 1); 346 ret = namebuf; 347 } 348 preempt_enable(); 349 350 return ret; 351} 352 353int lookup_module_symbol_name(unsigned long addr, char *symname) 354{ 355 struct module *mod; 356 357 preempt_disable(); 358 list_for_each_entry_rcu(mod, &modules, list) { 359 if (mod->state == MODULE_STATE_UNFORMED) 360 continue; 361 if (within_module(addr, mod)) { 362 const char *sym; 363 364 sym = find_kallsyms_symbol(mod, addr, NULL, NULL); 365 if (!sym) 366 goto out; 367 368 strscpy(symname, sym, KSYM_NAME_LEN); 369 preempt_enable(); 370 return 0; 371 } 372 } 373out: 374 preempt_enable(); 375 return -ERANGE; 376} 377 378int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, 379 unsigned long *offset, char *modname, char *name) 380{ 381 struct module *mod; 382 383 preempt_disable(); 384 list_for_each_entry_rcu(mod, &modules, list) { 385 if (mod->state == MODULE_STATE_UNFORMED) 386 continue; 387 if (within_module(addr, mod)) { 388 const char *sym; 389 390 sym = find_kallsyms_symbol(mod, addr, size, offset); 391 if (!sym) 392 goto out; 393 if (modname) 394 strscpy(modname, mod->name, MODULE_NAME_LEN); 395 if (name) 396 strscpy(name, sym, KSYM_NAME_LEN); 397 preempt_enable(); 398 return 0; 399 } 400 } 401out: 402 preempt_enable(); 403 return -ERANGE; 404} 405 406int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, 407 char *name, char *module_name, int *exported) 408{ 409 struct module *mod; 410 411 preempt_disable(); 412 list_for_each_entry_rcu(mod, &modules, list) { 413 struct mod_kallsyms *kallsyms; 414 415 if (mod->state == MODULE_STATE_UNFORMED) 416 continue; 417 kallsyms = rcu_dereference_sched(mod->kallsyms); 418 if (symnum < kallsyms->num_symtab) { 419 const Elf_Sym *sym = &kallsyms->symtab[symnum]; 420 421 *value = kallsyms_symbol_value(sym); 422 *type = kallsyms->typetab[symnum]; 423 strscpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN); 424 strscpy(module_name, mod->name, MODULE_NAME_LEN); 425 *exported = is_exported(name, *value, mod); 426 preempt_enable(); 427 return 0; 428 } 429 symnum -= kallsyms->num_symtab; 430 } 431 preempt_enable(); 432 return -ERANGE; 433} 434 435/* Given a module and name of symbol, find and return the symbol's value */ 436unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name) 437{ 438 unsigned int i; 439 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); 440 441 for (i = 0; i < kallsyms->num_symtab; i++) { 442 const Elf_Sym *sym = &kallsyms->symtab[i]; 443 444 if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 && 445 sym->st_shndx != SHN_UNDEF) 446 return kallsyms_symbol_value(sym); 447 } 448 return 0; 449} 450 451/* Look for this name: can be of form module:name. */ 452unsigned long module_kallsyms_lookup_name(const char *name) 453{ 454 struct module *mod; 455 char *colon; 456 unsigned long ret = 0; 457 458 /* Don't lock: we're in enough trouble already. */ 459 preempt_disable(); 460 if ((colon = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) { 461 if ((mod = find_module_all(name, colon - name, false)) != NULL) 462 ret = find_kallsyms_symbol_value(mod, colon + 1); 463 } else { 464 list_for_each_entry_rcu(mod, &modules, list) { 465 if (mod->state == MODULE_STATE_UNFORMED) 466 continue; 467 if ((ret = find_kallsyms_symbol_value(mod, name)) != 0) 468 break; 469 } 470 } 471 preempt_enable(); 472 return ret; 473} 474 475#ifdef CONFIG_LIVEPATCH 476int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, 477 struct module *, unsigned long), 478 void *data) 479{ 480 struct module *mod; 481 unsigned int i; 482 int ret = 0; 483 484 mutex_lock(&module_mutex); 485 list_for_each_entry(mod, &modules, list) { 486 struct mod_kallsyms *kallsyms; 487 488 if (mod->state == MODULE_STATE_UNFORMED) 489 continue; 490 491 /* Use rcu_dereference_sched() to remain compliant with the sparse tool */ 492 preempt_disable(); 493 kallsyms = rcu_dereference_sched(mod->kallsyms); 494 preempt_enable(); 495 496 for (i = 0; i < kallsyms->num_symtab; i++) { 497 const Elf_Sym *sym = &kallsyms->symtab[i]; 498 499 if (sym->st_shndx == SHN_UNDEF) 500 continue; 501 502 ret = fn(data, kallsyms_symbol_name(kallsyms, i), 503 mod, kallsyms_symbol_value(sym)); 504 if (ret != 0) 505 goto out; 506 } 507 } 508out: 509 mutex_unlock(&module_mutex); 510 return ret; 511} 512#endif /* CONFIG_LIVEPATCH */