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 */ 15 static 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 23 static 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 */ 37 static 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 77 static 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 */ 110 void 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 /* Note add_kallsyms() computes strtab_size as core_typeoffs - stroffs */ 141 info->core_typeoffs = mod->data_layout.size; 142 mod->data_layout.size += ndst * sizeof(char); 143 mod->data_layout.size = strict_align(mod->data_layout.size); 144 145 /* Put string table section at end of init part of module. */ 146 strsect->sh_flags |= SHF_ALLOC; 147 strsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, strsect, 148 info->index.str) | INIT_OFFSET_MASK; 149 pr_debug("\t%s\n", info->secstrings + strsect->sh_name); 150 151 /* We'll tack temporary mod_kallsyms on the end. */ 152 mod->init_layout.size = ALIGN(mod->init_layout.size, 153 __alignof__(struct mod_kallsyms)); 154 info->mod_kallsyms_init_off = mod->init_layout.size; 155 mod->init_layout.size += sizeof(struct mod_kallsyms); 156 info->init_typeoffs = mod->init_layout.size; 157 mod->init_layout.size += nsrc * sizeof(char); 158 mod->init_layout.size = strict_align(mod->init_layout.size); 159 } 160 161 /* 162 * We use the full symtab and strtab which layout_symtab arranged to 163 * be appended to the init section. Later we switch to the cut-down 164 * core-only ones. 165 */ 166 void add_kallsyms(struct module *mod, const struct load_info *info) 167 { 168 unsigned int i, ndst; 169 const Elf_Sym *src; 170 Elf_Sym *dst; 171 char *s; 172 Elf_Shdr *symsec = &info->sechdrs[info->index.sym]; 173 unsigned long strtab_size; 174 175 /* Set up to point into init section. */ 176 mod->kallsyms = (void __rcu *)mod->init_layout.base + 177 info->mod_kallsyms_init_off; 178 179 preempt_disable(); 180 /* The following is safe since this pointer cannot change */ 181 rcu_dereference_sched(mod->kallsyms)->symtab = (void *)symsec->sh_addr; 182 rcu_dereference_sched(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym); 183 /* Make sure we get permanent strtab: don't use info->strtab. */ 184 rcu_dereference_sched(mod->kallsyms)->strtab = 185 (void *)info->sechdrs[info->index.str].sh_addr; 186 rcu_dereference_sched(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs; 187 188 /* 189 * Now populate the cut down core kallsyms for after init 190 * and set types up while we still have access to sections. 191 */ 192 mod->core_kallsyms.symtab = dst = mod->data_layout.base + info->symoffs; 193 mod->core_kallsyms.strtab = s = mod->data_layout.base + info->stroffs; 194 mod->core_kallsyms.typetab = mod->data_layout.base + info->core_typeoffs; 195 strtab_size = info->core_typeoffs - info->stroffs; 196 src = rcu_dereference_sched(mod->kallsyms)->symtab; 197 for (ndst = i = 0; i < rcu_dereference_sched(mod->kallsyms)->num_symtab; i++) { 198 rcu_dereference_sched(mod->kallsyms)->typetab[i] = elf_type(src + i, info); 199 if (i == 0 || is_livepatch_module(mod) || 200 is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum, 201 info->index.pcpu)) { 202 ssize_t ret; 203 204 mod->core_kallsyms.typetab[ndst] = 205 rcu_dereference_sched(mod->kallsyms)->typetab[i]; 206 dst[ndst] = src[i]; 207 dst[ndst++].st_name = s - mod->core_kallsyms.strtab; 208 ret = strscpy(s, 209 &rcu_dereference_sched(mod->kallsyms)->strtab[src[i].st_name], 210 strtab_size); 211 if (ret < 0) 212 break; 213 s += ret + 1; 214 strtab_size -= ret + 1; 215 } 216 } 217 preempt_enable(); 218 mod->core_kallsyms.num_symtab = ndst; 219 } 220 221 #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) 222 void init_build_id(struct module *mod, const struct load_info *info) 223 { 224 const Elf_Shdr *sechdr; 225 unsigned int i; 226 227 for (i = 0; i < info->hdr->e_shnum; i++) { 228 sechdr = &info->sechdrs[i]; 229 if (!sect_empty(sechdr) && sechdr->sh_type == SHT_NOTE && 230 !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id, 231 sechdr->sh_size)) 232 break; 233 } 234 } 235 #else 236 void init_build_id(struct module *mod, const struct load_info *info) 237 { 238 } 239 #endif 240 241 /* 242 * This ignores the intensely annoying "mapping symbols" found 243 * in ARM ELF files: $a, $t and $d. 244 */ 245 static inline int is_arm_mapping_symbol(const char *str) 246 { 247 if (str[0] == '.' && str[1] == 'L') 248 return true; 249 return str[0] == '$' && strchr("axtd", str[1]) && 250 (str[2] == '\0' || str[2] == '.'); 251 } 252 253 static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum) 254 { 255 return kallsyms->strtab + kallsyms->symtab[symnum].st_name; 256 } 257 258 /* 259 * Given a module and address, find the corresponding symbol and return its name 260 * while providing its size and offset if needed. 261 */ 262 static const char *find_kallsyms_symbol(struct module *mod, 263 unsigned long addr, 264 unsigned long *size, 265 unsigned long *offset) 266 { 267 unsigned int i, best = 0; 268 unsigned long nextval, bestval; 269 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); 270 271 /* At worse, next value is at end of module */ 272 if (within_module_init(addr, mod)) 273 nextval = (unsigned long)mod->init_layout.base + mod->init_layout.text_size; 274 else 275 nextval = (unsigned long)mod->core_layout.base + mod->core_layout.text_size; 276 277 bestval = kallsyms_symbol_value(&kallsyms->symtab[best]); 278 279 /* 280 * Scan for closest preceding symbol, and next symbol. (ELF 281 * starts real symbols at 1). 282 */ 283 for (i = 1; i < kallsyms->num_symtab; i++) { 284 const Elf_Sym *sym = &kallsyms->symtab[i]; 285 unsigned long thisval = kallsyms_symbol_value(sym); 286 287 if (sym->st_shndx == SHN_UNDEF) 288 continue; 289 290 /* 291 * We ignore unnamed symbols: they're uninformative 292 * and inserted at a whim. 293 */ 294 if (*kallsyms_symbol_name(kallsyms, i) == '\0' || 295 is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) 296 continue; 297 298 if (thisval <= addr && thisval > bestval) { 299 best = i; 300 bestval = thisval; 301 } 302 if (thisval > addr && thisval < nextval) 303 nextval = thisval; 304 } 305 306 if (!best) 307 return NULL; 308 309 if (size) 310 *size = nextval - bestval; 311 if (offset) 312 *offset = addr - bestval; 313 314 return kallsyms_symbol_name(kallsyms, best); 315 } 316 317 void * __weak dereference_module_function_descriptor(struct module *mod, 318 void *ptr) 319 { 320 return ptr; 321 } 322 323 /* 324 * For kallsyms to ask for address resolution. NULL means not found. Careful 325 * not to lock to avoid deadlock on oopses, simply disable preemption. 326 */ 327 const char *module_address_lookup(unsigned long addr, 328 unsigned long *size, 329 unsigned long *offset, 330 char **modname, 331 const unsigned char **modbuildid, 332 char *namebuf) 333 { 334 const char *ret = NULL; 335 struct module *mod; 336 337 preempt_disable(); 338 mod = __module_address(addr); 339 if (mod) { 340 if (modname) 341 *modname = mod->name; 342 if (modbuildid) { 343 #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) 344 *modbuildid = mod->build_id; 345 #else 346 *modbuildid = NULL; 347 #endif 348 } 349 350 ret = find_kallsyms_symbol(mod, addr, size, offset); 351 } 352 /* Make a copy in here where it's safe */ 353 if (ret) { 354 strncpy(namebuf, ret, KSYM_NAME_LEN - 1); 355 ret = namebuf; 356 } 357 preempt_enable(); 358 359 return ret; 360 } 361 362 int lookup_module_symbol_name(unsigned long addr, char *symname) 363 { 364 struct module *mod; 365 366 preempt_disable(); 367 list_for_each_entry_rcu(mod, &modules, list) { 368 if (mod->state == MODULE_STATE_UNFORMED) 369 continue; 370 if (within_module(addr, mod)) { 371 const char *sym; 372 373 sym = find_kallsyms_symbol(mod, addr, NULL, NULL); 374 if (!sym) 375 goto out; 376 377 strscpy(symname, sym, KSYM_NAME_LEN); 378 preempt_enable(); 379 return 0; 380 } 381 } 382 out: 383 preempt_enable(); 384 return -ERANGE; 385 } 386 387 int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, 388 unsigned long *offset, char *modname, char *name) 389 { 390 struct module *mod; 391 392 preempt_disable(); 393 list_for_each_entry_rcu(mod, &modules, list) { 394 if (mod->state == MODULE_STATE_UNFORMED) 395 continue; 396 if (within_module(addr, mod)) { 397 const char *sym; 398 399 sym = find_kallsyms_symbol(mod, addr, size, offset); 400 if (!sym) 401 goto out; 402 if (modname) 403 strscpy(modname, mod->name, MODULE_NAME_LEN); 404 if (name) 405 strscpy(name, sym, KSYM_NAME_LEN); 406 preempt_enable(); 407 return 0; 408 } 409 } 410 out: 411 preempt_enable(); 412 return -ERANGE; 413 } 414 415 int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, 416 char *name, char *module_name, int *exported) 417 { 418 struct module *mod; 419 420 preempt_disable(); 421 list_for_each_entry_rcu(mod, &modules, list) { 422 struct mod_kallsyms *kallsyms; 423 424 if (mod->state == MODULE_STATE_UNFORMED) 425 continue; 426 kallsyms = rcu_dereference_sched(mod->kallsyms); 427 if (symnum < kallsyms->num_symtab) { 428 const Elf_Sym *sym = &kallsyms->symtab[symnum]; 429 430 *value = kallsyms_symbol_value(sym); 431 *type = kallsyms->typetab[symnum]; 432 strscpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN); 433 strscpy(module_name, mod->name, MODULE_NAME_LEN); 434 *exported = is_exported(name, *value, mod); 435 preempt_enable(); 436 return 0; 437 } 438 symnum -= kallsyms->num_symtab; 439 } 440 preempt_enable(); 441 return -ERANGE; 442 } 443 444 /* Given a module and name of symbol, find and return the symbol's value */ 445 unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name) 446 { 447 unsigned int i; 448 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); 449 450 for (i = 0; i < kallsyms->num_symtab; i++) { 451 const Elf_Sym *sym = &kallsyms->symtab[i]; 452 453 if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 && 454 sym->st_shndx != SHN_UNDEF) 455 return kallsyms_symbol_value(sym); 456 } 457 return 0; 458 } 459 460 /* Look for this name: can be of form module:name. */ 461 unsigned long module_kallsyms_lookup_name(const char *name) 462 { 463 struct module *mod; 464 char *colon; 465 unsigned long ret = 0; 466 467 /* Don't lock: we're in enough trouble already. */ 468 preempt_disable(); 469 if ((colon = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) { 470 if ((mod = find_module_all(name, colon - name, false)) != NULL) 471 ret = find_kallsyms_symbol_value(mod, colon + 1); 472 } else { 473 list_for_each_entry_rcu(mod, &modules, list) { 474 if (mod->state == MODULE_STATE_UNFORMED) 475 continue; 476 if ((ret = find_kallsyms_symbol_value(mod, name)) != 0) 477 break; 478 } 479 } 480 preempt_enable(); 481 return ret; 482 } 483 484 #ifdef CONFIG_LIVEPATCH 485 int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, 486 struct module *, unsigned long), 487 void *data) 488 { 489 struct module *mod; 490 unsigned int i; 491 int ret = 0; 492 493 mutex_lock(&module_mutex); 494 list_for_each_entry(mod, &modules, list) { 495 struct mod_kallsyms *kallsyms; 496 497 if (mod->state == MODULE_STATE_UNFORMED) 498 continue; 499 500 /* Use rcu_dereference_sched() to remain compliant with the sparse tool */ 501 preempt_disable(); 502 kallsyms = rcu_dereference_sched(mod->kallsyms); 503 preempt_enable(); 504 505 for (i = 0; i < kallsyms->num_symtab; i++) { 506 const Elf_Sym *sym = &kallsyms->symtab[i]; 507 508 if (sym->st_shndx == SHN_UNDEF) 509 continue; 510 511 ret = fn(data, kallsyms_symbol_name(kallsyms, i), 512 mod, kallsyms_symbol_value(sym)); 513 if (ret != 0) 514 goto out; 515 } 516 } 517 out: 518 mutex_unlock(&module_mutex); 519 return ret; 520 } 521 #endif /* CONFIG_LIVEPATCH */ 522