1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <compiler.h> 8 #include <confine_array_index.h> 9 #include <elf32.h> 10 #include <elf64.h> 11 #include <elf_common.h> 12 #include <string.h> 13 #include <tee_api_types.h> 14 #include <util.h> 15 16 #include "sys.h" 17 #include "ta_elf.h" 18 19 static uint32_t elf_hash(const char *name) 20 { 21 const unsigned char *p = (const unsigned char *)name; 22 uint32_t h = 0; 23 uint32_t g = 0; 24 25 while (*p) { 26 h = (h << 4) + *p++; 27 g = h & 0xf0000000; 28 if (g) 29 h ^= g >> 24; 30 h &= ~g; 31 } 32 return h; 33 } 34 35 static bool __resolve_sym(struct ta_elf *elf, unsigned int st_bind, 36 unsigned int st_type, size_t st_shndx, 37 size_t st_name, size_t st_value, const char *name, 38 vaddr_t *val, bool weak_ok) 39 { 40 bool bind_ok = false; 41 42 if (!st_name) 43 return false; 44 if (st_name > elf->dynstr_size) 45 err(TEE_ERROR_BAD_FORMAT, "Symbol name out of range"); 46 if (strcmp(name, elf->dynstr + st_name)) 47 return false; 48 if (st_bind == STB_GLOBAL || (weak_ok && st_bind == STB_WEAK)) 49 bind_ok = true; 50 if (!bind_ok) 51 return false; 52 if (st_bind == STB_WEAK && st_shndx == SHN_UNDEF) { 53 if (val) 54 *val = 0; 55 return true; 56 } 57 if (st_shndx == SHN_UNDEF || st_shndx == SHN_XINDEX) 58 return false; 59 60 switch (st_type) { 61 case STT_NOTYPE: 62 case STT_OBJECT: 63 case STT_FUNC: 64 if (st_value > (elf->max_addr - elf->load_addr)) 65 err(TEE_ERROR_BAD_FORMAT, 66 "Symbol location out of range"); 67 if (val) 68 *val = st_value + elf->load_addr; 69 break; 70 case STT_TLS: 71 if (val) 72 *val = st_value; 73 break; 74 default: 75 err(TEE_ERROR_NOT_SUPPORTED, "Symbol type not supported"); 76 } 77 78 return true; 79 } 80 81 static TEE_Result resolve_sym_helper(uint32_t hash, const char *name, 82 vaddr_t *val, struct ta_elf *elf, 83 bool weak_ok) 84 { 85 /* 86 * Using uint32_t here for convenience because both Elf64_Word 87 * and Elf32_Word are 32-bit types 88 */ 89 uint32_t *hashtab = elf->hashtab; 90 uint32_t nbuckets = hashtab[0]; 91 uint32_t nchains = hashtab[1]; 92 uint32_t *bucket = &hashtab[2]; 93 uint32_t *chain = &bucket[nbuckets]; 94 size_t n = 0; 95 96 if (elf->is_32bit) { 97 Elf32_Sym *sym = elf->dynsymtab; 98 99 for (n = bucket[hash % nbuckets]; n; n = chain[n]) { 100 if (n >= nchains || n >= elf->num_dynsyms) 101 err(TEE_ERROR_BAD_FORMAT, 102 "Index out of range"); 103 /* 104 * We're loading values from sym[] which later 105 * will be used to load something. 106 * => Spectre V1 pattern, need to cap the index 107 * against speculation. 108 */ 109 n = confine_array_index(n, elf->num_dynsyms); 110 if (__resolve_sym(elf, 111 ELF32_ST_BIND(sym[n].st_info), 112 ELF32_ST_TYPE(sym[n].st_info), 113 sym[n].st_shndx, 114 sym[n].st_name, 115 sym[n].st_value, name, val, weak_ok)) 116 return TEE_SUCCESS; 117 } 118 } else { 119 Elf64_Sym *sym = elf->dynsymtab; 120 121 for (n = bucket[hash % nbuckets]; n; n = chain[n]) { 122 if (n >= nchains || n >= elf->num_dynsyms) 123 err(TEE_ERROR_BAD_FORMAT, 124 "Index out of range"); 125 /* 126 * We're loading values from sym[] which later 127 * will be used to load something. 128 * => Spectre V1 pattern, need to cap the index 129 * against speculation. 130 */ 131 n = confine_array_index(n, elf->num_dynsyms); 132 if (__resolve_sym(elf, 133 ELF64_ST_BIND(sym[n].st_info), 134 ELF64_ST_TYPE(sym[n].st_info), 135 sym[n].st_shndx, 136 sym[n].st_name, 137 sym[n].st_value, name, val, weak_ok)) 138 return TEE_SUCCESS; 139 } 140 } 141 142 return TEE_ERROR_ITEM_NOT_FOUND; 143 } 144 145 /* 146 * Look for named symbol in @elf, or all modules if @elf == NULL. Global symbols 147 * are searched first, then weak ones. Last option, when at least one weak but 148 * undefined symbol exists, resolve to zero. Otherwise return 149 * TEE_ERROR_ITEM_NOT_FOUND. 150 * @val (if != 0) receives the symbol value 151 * @found_elf (if != 0) receives the module where the symbol is found 152 */ 153 TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val, 154 struct ta_elf **found_elf, 155 struct ta_elf *elf) 156 { 157 uint32_t hash = elf_hash(name); 158 159 if (elf) { 160 /* Search global symbols */ 161 if (!resolve_sym_helper(hash, name, val, elf, 162 false /* !weak_ok */)) 163 goto success; 164 /* Search weak symbols */ 165 if (!resolve_sym_helper(hash, name, val, elf, 166 true /* weak_ok */)) 167 goto success; 168 } 169 170 TAILQ_FOREACH(elf, &main_elf_queue, link) { 171 if (!resolve_sym_helper(hash, name, val, elf, 172 false /* !weak_ok */)) 173 goto success; 174 if (!resolve_sym_helper(hash, name, val, elf, 175 true /* weak_ok */)) 176 goto success; 177 } 178 179 return TEE_ERROR_ITEM_NOT_FOUND; 180 181 success: 182 if (found_elf) 183 *found_elf = elf; 184 return TEE_SUCCESS; 185 } 186 187 static void e32_get_sym_name(const Elf32_Sym *sym_tab, size_t num_syms, 188 const char *str_tab, size_t str_tab_size, 189 Elf32_Rel *rel, const char **name) 190 { 191 size_t sym_idx = 0; 192 size_t name_idx = 0; 193 194 sym_idx = ELF32_R_SYM(rel->r_info); 195 if (sym_idx >= num_syms) 196 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 197 sym_idx = confine_array_index(sym_idx, num_syms); 198 199 name_idx = sym_tab[sym_idx].st_name; 200 if (name_idx >= str_tab_size) 201 err(TEE_ERROR_BAD_FORMAT, "Name index out of range"); 202 *name = str_tab + name_idx; 203 } 204 205 static void resolve_sym(const char *name, vaddr_t *val, struct ta_elf **mod) 206 { 207 TEE_Result res = ta_elf_resolve_sym(name, val, mod, NULL); 208 209 if (res) 210 err(res, "Symbol %s not found", name); 211 } 212 213 static void e32_process_dyn_rel(const Elf32_Sym *sym_tab, size_t num_syms, 214 const char *str_tab, size_t str_tab_size, 215 Elf32_Rel *rel, Elf32_Addr *where) 216 { 217 const char *name = NULL; 218 vaddr_t val = 0; 219 220 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name); 221 resolve_sym(name, &val, NULL); 222 *where = val; 223 } 224 225 static void e32_tls_get_module(const Elf32_Sym *sym_tab, size_t num_syms, 226 const char *str_tab, size_t str_tab_size, 227 Elf32_Rel *rel, struct ta_elf **mod) 228 { 229 const char *name = NULL; 230 size_t sym_idx = 0; 231 232 sym_idx = ELF32_R_SYM(rel->r_info); 233 if (sym_idx >= num_syms) 234 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 235 sym_idx = confine_array_index(sym_idx, num_syms); 236 if (!sym_idx || sym_tab[sym_idx].st_shndx != SHN_UNDEF) { 237 /* No symbol, or symbol is defined in current module */ 238 return; 239 } 240 241 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name); 242 resolve_sym(name, NULL, mod); 243 } 244 245 static void e32_tls_resolve(const Elf32_Sym *sym_tab, size_t num_syms, 246 const char *str_tab, size_t str_tab_size, 247 Elf32_Rel *rel, vaddr_t *val) 248 { 249 const char *name = NULL; 250 251 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name); 252 resolve_sym(name, val, NULL); 253 } 254 255 static void e32_relocate(struct ta_elf *elf, unsigned int rel_sidx) 256 { 257 Elf32_Shdr *shdr = elf->shdr; 258 Elf32_Rel *rel = NULL; 259 Elf32_Rel *rel_end = NULL; 260 size_t sym_tab_idx = 0; 261 Elf32_Sym *sym_tab = NULL; 262 size_t num_syms = 0; 263 size_t sh_end = 0; 264 const char *str_tab = NULL; 265 size_t str_tab_size = 0; 266 267 assert(shdr[rel_sidx].sh_type == SHT_REL); 268 269 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf32_Rel)); 270 271 sym_tab_idx = shdr[rel_sidx].sh_link; 272 if (sym_tab_idx) { 273 size_t str_tab_idx = 0; 274 275 if (sym_tab_idx >= elf->e_shnum) 276 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range"); 277 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum); 278 279 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf32_Sym)); 280 281 /* Check the address is inside ELF memory */ 282 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 283 shdr[sym_tab_idx].sh_size, &sh_end)) 284 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 285 if (sh_end >= (elf->max_addr - elf->load_addr)) 286 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range"); 287 288 sym_tab = (Elf32_Sym *)(elf->load_addr + 289 shdr[sym_tab_idx].sh_addr); 290 291 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf32_Sym); 292 293 str_tab_idx = shdr[sym_tab_idx].sh_link; 294 if (str_tab_idx) { 295 if (str_tab_idx >= elf->e_shnum) 296 err(TEE_ERROR_BAD_FORMAT, 297 "STRTAB index out of range"); 298 str_tab_idx = confine_array_index(str_tab_idx, 299 elf->e_shnum); 300 301 /* Check the address is inside ELF memory */ 302 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 303 shdr[str_tab_idx].sh_size, &sh_end)) 304 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 305 if (sh_end >= (elf->max_addr - elf->load_addr)) 306 err(TEE_ERROR_BAD_FORMAT, 307 "STRTAB out of range"); 308 309 str_tab = (const char *)(elf->load_addr + 310 shdr[str_tab_idx].sh_addr); 311 str_tab_size = shdr[str_tab_idx].sh_size; 312 } 313 } 314 315 /* Check the address is inside TA memory */ 316 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, 317 shdr[rel_sidx].sh_size, &sh_end)) 318 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 319 if (sh_end >= (elf->max_addr - elf->load_addr)) 320 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range"); 321 rel = (Elf32_Rel *)(elf->load_addr + shdr[rel_sidx].sh_addr); 322 323 rel_end = rel + shdr[rel_sidx].sh_size / sizeof(Elf32_Rel); 324 for (; rel < rel_end; rel++) { 325 struct ta_elf *mod = NULL; 326 Elf32_Addr *where = NULL; 327 size_t sym_idx = 0; 328 vaddr_t val = 0; 329 330 /* Check the address is inside TA memory */ 331 if (rel->r_offset >= (elf->max_addr - elf->load_addr)) 332 err(TEE_ERROR_BAD_FORMAT, 333 "Relocation offset out of range"); 334 where = (Elf32_Addr *)(elf->load_addr + rel->r_offset); 335 336 switch (ELF32_R_TYPE(rel->r_info)) { 337 case R_ARM_ABS32: 338 sym_idx = ELF32_R_SYM(rel->r_info); 339 if (sym_idx >= num_syms) 340 err(TEE_ERROR_BAD_FORMAT, 341 "Symbol index out of range"); 342 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 343 /* Symbol is external */ 344 e32_process_dyn_rel(sym_tab, num_syms, str_tab, 345 str_tab_size, rel, where); 346 } else { 347 *where += elf->load_addr + 348 sym_tab[sym_idx].st_value; 349 } 350 break; 351 case R_ARM_REL32: 352 sym_idx = ELF32_R_SYM(rel->r_info); 353 if (sym_idx >= num_syms) 354 err(TEE_ERROR_BAD_FORMAT, 355 "Symbol index out of range"); 356 *where += sym_tab[sym_idx].st_value - rel->r_offset; 357 break; 358 case R_ARM_RELATIVE: 359 *where += elf->load_addr; 360 break; 361 case R_ARM_GLOB_DAT: 362 case R_ARM_JUMP_SLOT: 363 e32_process_dyn_rel(sym_tab, num_syms, str_tab, 364 str_tab_size, rel, where); 365 break; 366 case R_ARM_TLS_DTPMOD32: 367 mod = elf; 368 e32_tls_get_module(sym_tab, num_syms, str_tab, 369 str_tab_size, rel, &mod); 370 *where = mod->tls_mod_id; 371 break; 372 case R_ARM_TLS_DTPOFF32: 373 e32_tls_resolve(sym_tab, num_syms, str_tab, 374 str_tab_size, rel, &val); 375 *where = val; 376 break; 377 default: 378 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %d", 379 ELF32_R_TYPE(rel->r_info)); 380 } 381 } 382 } 383 384 #ifdef ARM64 385 static void e64_get_sym_name(const Elf64_Sym *sym_tab, size_t num_syms, 386 const char *str_tab, size_t str_tab_size, 387 Elf64_Rela *rela, const char **name) 388 { 389 size_t sym_idx = 0; 390 size_t name_idx = 0; 391 392 sym_idx = ELF64_R_SYM(rela->r_info); 393 if (sym_idx >= num_syms) 394 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 395 sym_idx = confine_array_index(sym_idx, num_syms); 396 397 name_idx = sym_tab[sym_idx].st_name; 398 if (name_idx >= str_tab_size) 399 err(TEE_ERROR_BAD_FORMAT, "Name index out of range"); 400 *name = str_tab + name_idx; 401 } 402 403 static void e64_process_dyn_rela(const Elf64_Sym *sym_tab, size_t num_syms, 404 const char *str_tab, size_t str_tab_size, 405 Elf64_Rela *rela, Elf64_Addr *where) 406 { 407 const char *name = NULL; 408 uintptr_t val = 0; 409 410 e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, &name); 411 resolve_sym(name, &val, NULL); 412 *where = val; 413 } 414 415 static void e64_process_tls_rela(const Elf64_Sym *sym_tab, size_t num_syms, 416 const char *str_tab, size_t str_tab_size, 417 Elf64_Rela *rela, Elf64_Addr *where) 418 { 419 struct ta_elf *mod = NULL; 420 const char *name = NULL; 421 vaddr_t symval = 0; 422 423 e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, &name); 424 resolve_sym(name, &symval, &mod); 425 *where = symval + mod->tls_tcb_offs + rela->r_addend; 426 } 427 428 static void e64_relocate(struct ta_elf *elf, unsigned int rel_sidx) 429 { 430 Elf64_Shdr *shdr = elf->shdr; 431 Elf64_Rela *rela = NULL; 432 Elf64_Rela *rela_end = NULL; 433 size_t sym_tab_idx = 0; 434 Elf64_Sym *sym_tab = NULL; 435 size_t num_syms = 0; 436 size_t sh_end = 0; 437 const char *str_tab = NULL; 438 size_t str_tab_size = 0; 439 440 assert(shdr[rel_sidx].sh_type == SHT_RELA); 441 442 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf64_Rela)); 443 444 sym_tab_idx = shdr[rel_sidx].sh_link; 445 if (sym_tab_idx) { 446 size_t str_tab_idx = 0; 447 448 if (sym_tab_idx >= elf->e_shnum) 449 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range"); 450 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum); 451 452 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf64_Sym)); 453 454 /* Check the address is inside TA memory */ 455 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 456 shdr[sym_tab_idx].sh_size, &sh_end)) 457 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 458 if (sh_end >= (elf->max_addr - elf->load_addr)) 459 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range"); 460 461 sym_tab = (Elf64_Sym *)(elf->load_addr + 462 shdr[sym_tab_idx].sh_addr); 463 464 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf64_Sym); 465 466 str_tab_idx = shdr[sym_tab_idx].sh_link; 467 if (str_tab_idx) { 468 if (str_tab_idx >= elf->e_shnum) 469 err(TEE_ERROR_BAD_FORMAT, 470 "STRTAB index out of range"); 471 str_tab_idx = confine_array_index(str_tab_idx, 472 elf->e_shnum); 473 474 /* Check the address is inside ELF memory */ 475 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 476 shdr[str_tab_idx].sh_size, &sh_end)) 477 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 478 if (sh_end >= (elf->max_addr - elf->load_addr)) 479 err(TEE_ERROR_BAD_FORMAT, 480 "STRTAB out of range"); 481 482 str_tab = (const char *)(elf->load_addr + 483 shdr[str_tab_idx].sh_addr); 484 str_tab_size = shdr[str_tab_idx].sh_size; 485 } 486 } 487 488 /* Check the address is inside TA memory */ 489 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, 490 shdr[rel_sidx].sh_size, &sh_end)) 491 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 492 if (sh_end >= (elf->max_addr - elf->load_addr)) 493 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range"); 494 rela = (Elf64_Rela *)(elf->load_addr + shdr[rel_sidx].sh_addr); 495 496 rela_end = rela + shdr[rel_sidx].sh_size / sizeof(Elf64_Rela); 497 for (; rela < rela_end; rela++) { 498 Elf64_Addr *where = NULL; 499 size_t sym_idx = 0; 500 501 /* Check the address is inside TA memory */ 502 if (rela->r_offset >= (elf->max_addr - elf->load_addr)) 503 err(TEE_ERROR_BAD_FORMAT, 504 "Relocation offset out of range"); 505 506 where = (Elf64_Addr *)(elf->load_addr + rela->r_offset); 507 508 switch (ELF64_R_TYPE(rela->r_info)) { 509 case R_AARCH64_ABS64: 510 sym_idx = ELF64_R_SYM(rela->r_info); 511 if (sym_idx >= num_syms) 512 err(TEE_ERROR_BAD_FORMAT, 513 "Symbol index out of range"); 514 sym_idx = confine_array_index(sym_idx, num_syms); 515 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 516 /* Symbol is external */ 517 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 518 str_tab_size, rela, where); 519 } else { 520 *where = rela->r_addend + elf->load_addr + 521 sym_tab[sym_idx].st_value; 522 } 523 break; 524 case R_AARCH64_RELATIVE: 525 *where = rela->r_addend + elf->load_addr; 526 break; 527 case R_AARCH64_GLOB_DAT: 528 case R_AARCH64_JUMP_SLOT: 529 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 530 str_tab_size, rela, where); 531 break; 532 case R_AARCH64_TLS_TPREL: 533 e64_process_tls_rela(sym_tab, num_syms, str_tab, 534 str_tab_size, rela, where); 535 break; 536 default: 537 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %zd", 538 ELF64_R_TYPE(rela->r_info)); 539 } 540 } 541 } 542 #else /*ARM64*/ 543 static void __noreturn e64_relocate(struct ta_elf *elf __unused, 544 unsigned int rel_sidx __unused) 545 { 546 err(TEE_ERROR_NOT_SUPPORTED, "arm64 not supported"); 547 } 548 #endif /*ARM64*/ 549 550 void ta_elf_relocate(struct ta_elf *elf) 551 { 552 size_t n = 0; 553 554 if (elf->is_32bit) { 555 Elf32_Shdr *shdr = elf->shdr; 556 557 for (n = 0; n < elf->e_shnum; n++) 558 if (shdr[n].sh_type == SHT_REL) 559 e32_relocate(elf, n); 560 } else { 561 Elf64_Shdr *shdr = elf->shdr; 562 563 for (n = 0; n < elf->e_shnum; n++) 564 if (shdr[n].sh_type == SHT_RELA) 565 e64_relocate(elf, n); 566 567 } 568 } 569