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 uint32_t gnu_hash(const char *name) 36 { 37 const unsigned char *p = (const unsigned char *)name; 38 uint32_t h = 5381; 39 40 while (*p) 41 h = (h << 5) + h + *p++; 42 43 return h; 44 } 45 46 static bool sym_compare(struct ta_elf *elf, unsigned int st_bind, 47 unsigned int st_type, size_t st_shndx, 48 size_t st_name, size_t st_value, const char *name, 49 vaddr_t *val, bool weak_ok) 50 { 51 bool bind_ok = false; 52 53 if (!st_name) 54 return false; 55 if (st_name > elf->dynstr_size) 56 err(TEE_ERROR_BAD_FORMAT, "Symbol name out of range"); 57 if (strcmp(name, elf->dynstr + st_name)) 58 return false; 59 if (st_bind == STB_GLOBAL || (weak_ok && st_bind == STB_WEAK)) 60 bind_ok = true; 61 if (!bind_ok) 62 return false; 63 if (st_bind == STB_WEAK && st_shndx == SHN_UNDEF) { 64 if (val) 65 *val = 0; 66 return true; 67 } 68 if (st_shndx == SHN_UNDEF || st_shndx == SHN_XINDEX) 69 return false; 70 71 switch (st_type) { 72 case STT_NOTYPE: 73 case STT_OBJECT: 74 case STT_FUNC: 75 if (st_value > (elf->max_addr - elf->load_addr)) 76 err(TEE_ERROR_BAD_FORMAT, 77 "Symbol location out of range"); 78 if (val) 79 *val = st_value + elf->load_addr; 80 break; 81 case STT_TLS: 82 if (val) 83 *val = st_value; 84 break; 85 default: 86 err(TEE_ERROR_NOT_SUPPORTED, "Symbol type not supported"); 87 } 88 89 return true; 90 } 91 92 static bool check_found_sym(struct ta_elf *elf, const char *name, vaddr_t *val, 93 bool weak_ok, size_t n) 94 { 95 Elf32_Sym *sym32 = NULL; 96 Elf64_Sym *sym64 = NULL; 97 unsigned int st_bind = 0; 98 unsigned int st_type = 0; 99 size_t st_shndx = 0; 100 size_t st_name = 0; 101 size_t st_value = 0; 102 103 if (n >= elf->num_dynsyms) 104 err(TEE_ERROR_BAD_FORMAT, "Index out of range"); 105 106 /* 107 * We're loading values from sym[] which later 108 * will be used to load something. 109 * => Spectre V1 pattern, need to cap the index 110 * against speculation. 111 */ 112 n = confine_array_index(n, elf->num_dynsyms); 113 114 if (elf->is_32bit) { 115 sym32 = elf->dynsymtab; 116 st_bind = ELF32_ST_BIND(sym32[n].st_info); 117 st_type = ELF32_ST_TYPE(sym32[n].st_info); 118 st_shndx = sym32[n].st_shndx; 119 st_name = sym32[n].st_name; 120 st_value = sym32[n].st_value; 121 } else { 122 sym64 = elf->dynsymtab; 123 st_bind = ELF64_ST_BIND(sym64[n].st_info); 124 st_type = ELF64_ST_TYPE(sym64[n].st_info); 125 st_shndx = sym64[n].st_shndx; 126 st_name = sym64[n].st_name; 127 st_value = sym64[n].st_value; 128 } 129 130 return sym_compare(elf, st_bind, st_type, st_shndx, st_name, st_value, 131 name, val, weak_ok); 132 } 133 134 static TEE_Result resolve_sym_helper(const char *name, vaddr_t *val, 135 struct ta_elf *elf, bool weak_ok) 136 { 137 uint32_t n = 0; 138 uint32_t hash = 0; 139 140 if (elf->gnu_hashtab) { 141 struct gnu_hashtab *h = elf->gnu_hashtab; 142 uint32_t *end = (void *)((uint8_t *)elf->gnu_hashtab + 143 elf->gnu_hashtab_size); 144 uint32_t *bucket = NULL; 145 uint32_t *chain = NULL; 146 uint32_t hashval = 0; 147 148 hash = gnu_hash(name); 149 150 if (elf->is_32bit) { 151 uint32_t *bloom = (void *)(h + 1); 152 uint32_t word = bloom[(hash / 32) % h->bloom_size]; 153 uint32_t mask = BIT32(hash % 32) | 154 BIT32((hash >> h->bloom_shift) % 32); 155 156 if ((word & mask) != mask) 157 return TEE_ERROR_ITEM_NOT_FOUND; 158 bucket = bloom + h->bloom_size; 159 } else { 160 uint64_t *bloom = (void *)(h + 1); 161 uint64_t word = bloom[(hash / 64) % h->bloom_size]; 162 uint64_t mask = BIT64(hash % 64) | 163 BIT64((hash >> h->bloom_shift) % 64); 164 165 if ((word & mask) != mask) 166 return TEE_ERROR_ITEM_NOT_FOUND; 167 bucket = (uint32_t *)(bloom + h->bloom_size); 168 } 169 chain = bucket + h->nbuckets; 170 171 n = bucket[hash % h->nbuckets]; 172 if (n < h->symoffset) 173 return TEE_ERROR_ITEM_NOT_FOUND; 174 175 hash |= 1; 176 do { 177 size_t idx = n - h->symoffset; 178 179 if (chain + idx > end) 180 return TEE_ERROR_ITEM_NOT_FOUND; 181 182 hashval = chain[idx]; 183 184 if ((hashval | 1) == hash && 185 check_found_sym(elf, name, val, weak_ok, n)) 186 return TEE_SUCCESS; 187 188 n++; 189 } while (!(hashval & 1)); 190 } else if (elf->hashtab) { 191 /* 192 * Using uint32_t here for convenience because both Elf64_Word 193 * and Elf32_Word are 32-bit types 194 */ 195 uint32_t *hashtab = elf->hashtab; 196 uint32_t nbuckets = hashtab[0]; 197 uint32_t nchains = hashtab[1]; 198 uint32_t *bucket = &hashtab[2]; 199 uint32_t *chain = &bucket[nbuckets]; 200 201 if (!nbuckets) 202 return TEE_ERROR_ITEM_NOT_FOUND; 203 204 hash = elf_hash(name); 205 206 for (n = bucket[hash % nbuckets]; n; n = chain[n]) { 207 if (n >= nchains) 208 err(TEE_ERROR_BAD_FORMAT, "Index out of range"); 209 if (check_found_sym(elf, name, val, weak_ok, n)) 210 return TEE_SUCCESS; 211 } 212 } 213 214 return TEE_ERROR_ITEM_NOT_FOUND; 215 } 216 217 /* 218 * Look for named symbol in @elf, or all modules if @elf == NULL. Global symbols 219 * are searched first, then weak ones. Last option, when at least one weak but 220 * undefined symbol exists, resolve to zero. Otherwise return 221 * TEE_ERROR_ITEM_NOT_FOUND. 222 * @val (if != 0) receives the symbol value 223 * @found_elf (if != 0) receives the module where the symbol is found 224 */ 225 TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val, 226 struct ta_elf **found_elf, 227 struct ta_elf *elf) 228 { 229 if (elf) { 230 /* Search global symbols */ 231 if (!resolve_sym_helper(name, val, elf, false /* !weak_ok */)) 232 goto success; 233 /* Search weak symbols */ 234 if (!resolve_sym_helper(name, val, elf, true /* weak_ok */)) 235 goto success; 236 } 237 238 TAILQ_FOREACH(elf, &main_elf_queue, link) { 239 if (!resolve_sym_helper(name, val, elf, false /* !weak_ok */)) 240 goto success; 241 if (!resolve_sym_helper(name, val, elf, true /* weak_ok */)) 242 goto success; 243 } 244 245 return TEE_ERROR_ITEM_NOT_FOUND; 246 247 success: 248 if (found_elf) 249 *found_elf = elf; 250 return TEE_SUCCESS; 251 } 252 253 static void e32_get_sym_name(const Elf32_Sym *sym_tab, size_t num_syms, 254 const char *str_tab, size_t str_tab_size, 255 Elf32_Rel *rel, const char **name, 256 bool *weak_undef) 257 { 258 size_t sym_idx = 0; 259 size_t name_idx = 0; 260 261 sym_idx = ELF32_R_SYM(rel->r_info); 262 if (sym_idx >= num_syms) 263 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 264 sym_idx = confine_array_index(sym_idx, num_syms); 265 266 name_idx = sym_tab[sym_idx].st_name; 267 if (name_idx >= str_tab_size) 268 err(TEE_ERROR_BAD_FORMAT, "Name index out of range"); 269 *name = str_tab + name_idx; 270 271 if (!weak_undef) 272 return; 273 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF && 274 ELF32_ST_BIND(sym_tab[sym_idx].st_info) == STB_WEAK) 275 *weak_undef = true; 276 else 277 *weak_undef = false; 278 } 279 280 static void resolve_sym(const char *name, vaddr_t *val, struct ta_elf **mod, 281 bool err_if_not_found) 282 { 283 TEE_Result res = ta_elf_resolve_sym(name, val, mod, NULL); 284 285 if (res) { 286 if (err_if_not_found) 287 err(res, "Symbol %s not found", name); 288 else if (val) 289 *val = 0; 290 } 291 } 292 293 static void e32_process_dyn_rel(const Elf32_Sym *sym_tab, size_t num_syms, 294 const char *str_tab, size_t str_tab_size, 295 Elf32_Rel *rel, Elf32_Addr *where) 296 { 297 const char *name = NULL; 298 vaddr_t val = 0; 299 bool weak_undef = false; 300 301 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name, 302 &weak_undef); 303 resolve_sym(name, &val, NULL, !weak_undef); 304 *where = val; 305 } 306 307 static void e32_tls_get_module(const Elf32_Sym *sym_tab, size_t num_syms, 308 const char *str_tab, size_t str_tab_size, 309 Elf32_Rel *rel, struct ta_elf **mod) 310 { 311 const char *name = NULL; 312 size_t sym_idx = 0; 313 314 sym_idx = ELF32_R_SYM(rel->r_info); 315 if (sym_idx >= num_syms) 316 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 317 sym_idx = confine_array_index(sym_idx, num_syms); 318 if (!sym_idx || sym_tab[sym_idx].st_shndx != SHN_UNDEF) { 319 /* No symbol, or symbol is defined in current module */ 320 return; 321 } 322 323 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name, 324 NULL); 325 resolve_sym(name, NULL, mod, false); 326 } 327 328 static void e32_tls_resolve(const Elf32_Sym *sym_tab, size_t num_syms, 329 const char *str_tab, size_t str_tab_size, 330 Elf32_Rel *rel, vaddr_t *val) 331 { 332 const char *name = NULL; 333 334 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name, 335 NULL); 336 resolve_sym(name, val, NULL, false); 337 } 338 339 static void e32_relocate(struct ta_elf *elf, unsigned int rel_sidx) 340 { 341 Elf32_Shdr *shdr = elf->shdr; 342 Elf32_Rel *rel = NULL; 343 Elf32_Rel *rel_end = NULL; 344 size_t sym_tab_idx = 0; 345 Elf32_Sym *sym_tab = NULL; 346 size_t num_syms = 0; 347 size_t sh_end = 0; 348 const char *str_tab = NULL; 349 size_t str_tab_size = 0; 350 351 assert(shdr[rel_sidx].sh_type == SHT_REL); 352 353 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf32_Rel)); 354 355 sym_tab_idx = shdr[rel_sidx].sh_link; 356 if (sym_tab_idx) { 357 size_t str_tab_idx = 0; 358 359 if (sym_tab_idx >= elf->e_shnum) 360 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range"); 361 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum); 362 363 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf32_Sym)); 364 365 /* Check the address is inside ELF memory */ 366 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 367 shdr[sym_tab_idx].sh_size, &sh_end)) 368 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 369 if (sh_end >= (elf->max_addr - elf->load_addr)) 370 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range"); 371 372 sym_tab = (Elf32_Sym *)(elf->load_addr + 373 shdr[sym_tab_idx].sh_addr); 374 375 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf32_Sym); 376 377 str_tab_idx = shdr[sym_tab_idx].sh_link; 378 if (str_tab_idx) { 379 if (str_tab_idx >= elf->e_shnum) 380 err(TEE_ERROR_BAD_FORMAT, 381 "STRTAB index out of range"); 382 str_tab_idx = confine_array_index(str_tab_idx, 383 elf->e_shnum); 384 385 /* Check the address is inside ELF memory */ 386 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 387 shdr[str_tab_idx].sh_size, &sh_end)) 388 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 389 if (sh_end >= (elf->max_addr - elf->load_addr)) 390 err(TEE_ERROR_BAD_FORMAT, 391 "STRTAB out of range"); 392 393 str_tab = (const char *)(elf->load_addr + 394 shdr[str_tab_idx].sh_addr); 395 str_tab_size = shdr[str_tab_idx].sh_size; 396 } 397 } 398 399 /* Check the address is inside TA memory */ 400 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, 401 shdr[rel_sidx].sh_size, &sh_end)) 402 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 403 if (sh_end >= (elf->max_addr - elf->load_addr)) 404 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range"); 405 rel = (Elf32_Rel *)(elf->load_addr + shdr[rel_sidx].sh_addr); 406 407 rel_end = rel + shdr[rel_sidx].sh_size / sizeof(Elf32_Rel); 408 for (; rel < rel_end; rel++) { 409 struct ta_elf *mod = NULL; 410 Elf32_Addr *where = NULL; 411 Elf32_Addr end_offs = 0; 412 size_t sym_idx = 0; 413 vaddr_t val = 0; 414 415 /* Check the address is inside TA memory */ 416 if (ADD_OVERFLOW(rel->r_offset, sizeof(*where), &end_offs) || 417 end_offs >= (elf->max_addr - elf->load_addr)) 418 err(TEE_ERROR_BAD_FORMAT, 419 "Relocation offset out of range"); 420 where = (Elf32_Addr *)(elf->load_addr + rel->r_offset); 421 422 switch (ELF32_R_TYPE(rel->r_info)) { 423 case R_ARM_NONE: 424 /* 425 * One would expect linker prevents such useless entry 426 * in the relocation table. We still handle this type 427 * here in case such entries exist. 428 */ 429 break; 430 case R_ARM_ABS32: 431 sym_idx = ELF32_R_SYM(rel->r_info); 432 if (sym_idx >= num_syms) 433 err(TEE_ERROR_BAD_FORMAT, 434 "Symbol index out of range"); 435 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 436 /* Symbol is external */ 437 e32_process_dyn_rel(sym_tab, num_syms, str_tab, 438 str_tab_size, rel, where); 439 } else { 440 *where += elf->load_addr + 441 sym_tab[sym_idx].st_value; 442 } 443 break; 444 case R_ARM_REL32: 445 sym_idx = ELF32_R_SYM(rel->r_info); 446 if (sym_idx >= num_syms) 447 err(TEE_ERROR_BAD_FORMAT, 448 "Symbol index out of range"); 449 *where += sym_tab[sym_idx].st_value - rel->r_offset; 450 break; 451 case R_ARM_RELATIVE: 452 *where += elf->load_addr; 453 break; 454 case R_ARM_GLOB_DAT: 455 case R_ARM_JUMP_SLOT: 456 if (!sym_tab) 457 err(TEE_ERROR_BAD_FORMAT, 458 "Missing symbol table"); 459 e32_process_dyn_rel(sym_tab, num_syms, str_tab, 460 str_tab_size, rel, where); 461 break; 462 case R_ARM_TLS_DTPMOD32: 463 if (!sym_tab) 464 err(TEE_ERROR_BAD_FORMAT, 465 "Missing symbol table"); 466 mod = elf; 467 e32_tls_get_module(sym_tab, num_syms, str_tab, 468 str_tab_size, rel, &mod); 469 *where = mod->tls_mod_id; 470 break; 471 case R_ARM_TLS_DTPOFF32: 472 if (!sym_tab) 473 err(TEE_ERROR_BAD_FORMAT, 474 "Missing symbol table"); 475 e32_tls_resolve(sym_tab, num_syms, str_tab, 476 str_tab_size, rel, &val); 477 *where = val; 478 break; 479 default: 480 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %d", 481 ELF32_R_TYPE(rel->r_info)); 482 } 483 } 484 } 485 486 #if defined(ARM64) || defined(RV64) 487 static void e64_get_sym_name(const Elf64_Sym *sym_tab, size_t num_syms, 488 const char *str_tab, size_t str_tab_size, 489 Elf64_Rela *rela, const char **name, 490 bool *weak_undef) 491 { 492 size_t sym_idx = 0; 493 size_t name_idx = 0; 494 495 sym_idx = ELF64_R_SYM(rela->r_info); 496 if (sym_idx >= num_syms) 497 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 498 sym_idx = confine_array_index(sym_idx, num_syms); 499 500 name_idx = sym_tab[sym_idx].st_name; 501 if (name_idx >= str_tab_size) 502 err(TEE_ERROR_BAD_FORMAT, "Name index out of range"); 503 *name = str_tab + name_idx; 504 505 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF && 506 ELF64_ST_BIND(sym_tab[sym_idx].st_info) == STB_WEAK) 507 *weak_undef = true; 508 else 509 *weak_undef = false; 510 } 511 512 static void e64_process_dyn_rela(const Elf64_Sym *sym_tab, size_t num_syms, 513 const char *str_tab, size_t str_tab_size, 514 Elf64_Rela *rela, Elf64_Addr *where) 515 { 516 const char *name = NULL; 517 uintptr_t val = 0; 518 bool weak_undef = false; 519 520 e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, &name, 521 &weak_undef); 522 resolve_sym(name, &val, NULL, !weak_undef); 523 *where = val; 524 } 525 526 #ifdef ARM64 527 static void e64_process_tls_tprel_rela(const Elf64_Sym *sym_tab, 528 size_t num_syms, const char *str_tab, 529 size_t str_tab_size, Elf64_Rela *rela, 530 Elf64_Addr *where, struct ta_elf *elf) 531 { 532 struct ta_elf *mod = NULL; 533 bool weak_undef = false; 534 const char *name = NULL; 535 size_t sym_idx = 0; 536 vaddr_t symval = 0; 537 538 sym_idx = ELF64_R_SYM(rela->r_info); 539 if (sym_idx) { 540 e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, 541 &name, &weak_undef); 542 resolve_sym(name, &symval, &mod, !weak_undef); 543 } else { 544 mod = elf; 545 } 546 *where = symval + mod->tls_tcb_offs + rela->r_addend; 547 } 548 549 struct tlsdesc { 550 long (*resolver)(struct tlsdesc *td); 551 long value; 552 }; 553 554 /* Helper function written in assembly due to the calling convention */ 555 long tlsdesc_resolve(struct tlsdesc *td); 556 557 static void e64_process_tlsdesc_rela(const Elf64_Sym *sym_tab, size_t num_syms, 558 const char *str_tab, size_t str_tab_size, 559 Elf64_Rela *rela, Elf64_Addr *where, 560 struct ta_elf *elf) 561 { 562 /* 563 * @where points to a pair of 64-bit words in the GOT or PLT which is 564 * mapped to a struct tlsdesc: 565 * 566 * - resolver() must return the offset of the thread-local variable 567 * relative to TPIDR_EL0. 568 * - value is implementation-dependent. The TLS_TPREL handling code is 569 * re-used to get the desired offset so that tlsdesc_resolve() just 570 * needs to return this value. 571 * 572 * Both the TA and ldelf are AArch64 so it is OK to point to a function 573 * in ldelf. 574 */ 575 *where = (Elf64_Addr)tlsdesc_resolve; 576 e64_process_tls_tprel_rela(sym_tab, num_syms, str_tab, str_tab_size, 577 rela, where + 1, elf); 578 } 579 #endif /*ARM64*/ 580 581 static void e64_relocate(struct ta_elf *elf, unsigned int rel_sidx) 582 { 583 Elf64_Shdr *shdr = elf->shdr; 584 Elf64_Rela *rela = NULL; 585 Elf64_Rela *rela_end = NULL; 586 size_t sym_tab_idx = 0; 587 Elf64_Sym *sym_tab = NULL; 588 size_t num_syms = 0; 589 size_t sh_end = 0; 590 const char *str_tab = NULL; 591 size_t str_tab_size = 0; 592 593 assert(shdr[rel_sidx].sh_type == SHT_RELA); 594 595 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf64_Rela)); 596 597 sym_tab_idx = shdr[rel_sidx].sh_link; 598 if (sym_tab_idx) { 599 size_t str_tab_idx = 0; 600 601 if (sym_tab_idx >= elf->e_shnum) 602 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range"); 603 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum); 604 605 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf64_Sym)); 606 607 /* Check the address is inside TA memory */ 608 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 609 shdr[sym_tab_idx].sh_size, &sh_end)) 610 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 611 if (sh_end >= (elf->max_addr - elf->load_addr)) 612 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range"); 613 614 sym_tab = (Elf64_Sym *)(elf->load_addr + 615 shdr[sym_tab_idx].sh_addr); 616 617 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf64_Sym); 618 619 str_tab_idx = shdr[sym_tab_idx].sh_link; 620 if (str_tab_idx) { 621 if (str_tab_idx >= elf->e_shnum) 622 err(TEE_ERROR_BAD_FORMAT, 623 "STRTAB index out of range"); 624 str_tab_idx = confine_array_index(str_tab_idx, 625 elf->e_shnum); 626 627 /* Check the address is inside ELF memory */ 628 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 629 shdr[str_tab_idx].sh_size, &sh_end)) 630 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 631 if (sh_end >= (elf->max_addr - elf->load_addr)) 632 err(TEE_ERROR_BAD_FORMAT, 633 "STRTAB out of range"); 634 635 str_tab = (const char *)(elf->load_addr + 636 shdr[str_tab_idx].sh_addr); 637 str_tab_size = shdr[str_tab_idx].sh_size; 638 } 639 } 640 641 /* Check the address is inside TA memory */ 642 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, 643 shdr[rel_sidx].sh_size, &sh_end)) 644 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 645 if (sh_end >= (elf->max_addr - elf->load_addr)) 646 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range"); 647 rela = (Elf64_Rela *)(elf->load_addr + shdr[rel_sidx].sh_addr); 648 649 rela_end = rela + shdr[rel_sidx].sh_size / sizeof(Elf64_Rela); 650 for (; rela < rela_end; rela++) { 651 Elf64_Addr *where = NULL; 652 size_t write_size = sizeof(*where); 653 size_t sym_idx __maybe_unused = 0; 654 Elf64_Addr end_offs = 0; 655 656 if (ELF64_R_TYPE(rela->r_info) == R_AARCH64_TLSDESC) 657 write_size *= 2; 658 659 /* Check the address is inside TA memory */ 660 if (ADD_OVERFLOW(rela->r_offset, write_size, &end_offs) || 661 end_offs >= (elf->max_addr - elf->load_addr)) 662 err(TEE_ERROR_BAD_FORMAT, 663 "Relocation offset out of range"); 664 665 where = (Elf64_Addr *)(elf->load_addr + rela->r_offset); 666 667 switch (ELF64_R_TYPE(rela->r_info)) { 668 #ifdef ARM64 669 case R_AARCH64_NONE: 670 /* 671 * One would expect linker prevents such useless entry 672 * in the relocation table. We still handle this type 673 * here in case such entries exist. 674 */ 675 break; 676 case R_AARCH64_ABS64: 677 sym_idx = ELF64_R_SYM(rela->r_info); 678 if (sym_idx >= num_syms) 679 err(TEE_ERROR_BAD_FORMAT, 680 "Symbol index out of range"); 681 sym_idx = confine_array_index(sym_idx, num_syms); 682 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 683 /* Symbol is external */ 684 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 685 str_tab_size, rela, where); 686 } else { 687 *where = rela->r_addend + elf->load_addr + 688 sym_tab[sym_idx].st_value; 689 } 690 break; 691 case R_AARCH64_RELATIVE: 692 *where = rela->r_addend + elf->load_addr; 693 break; 694 case R_AARCH64_GLOB_DAT: 695 case R_AARCH64_JUMP_SLOT: 696 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 697 str_tab_size, rela, where); 698 break; 699 case R_AARCH64_TLS_TPREL: 700 e64_process_tls_tprel_rela(sym_tab, num_syms, str_tab, 701 str_tab_size, rela, where, 702 elf); 703 break; 704 case R_AARCH64_TLSDESC: 705 e64_process_tlsdesc_rela(sym_tab, num_syms, str_tab, 706 str_tab_size, rela, where, 707 elf); 708 break; 709 #endif /*ARM64*/ 710 #ifdef RV64 711 case R_RISCV_NONE: 712 /* 713 * One would expect linker prevents such useless entry 714 * in the relocation table. We still handle this type 715 * here in case such entries exist. 716 */ 717 break; 718 case R_RISCV_RELATIVE: 719 *where = rela->r_addend + elf->load_addr; 720 break; 721 case R_RISCV_64: 722 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 723 str_tab_size, rela, where); 724 *where += rela->r_addend; 725 break; 726 case R_RISCV_JUMP_SLOT: 727 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 728 str_tab_size, rela, where); 729 break; 730 #endif /*RV64*/ 731 default: 732 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %zd", 733 ELF64_R_TYPE(rela->r_info)); 734 } 735 } 736 } 737 #else /*ARM64 || RV64*/ 738 static void __noreturn e64_relocate(struct ta_elf *elf __unused, 739 unsigned int rel_sidx __unused) 740 { 741 err(TEE_ERROR_NOT_SUPPORTED, "arm64 not supported"); 742 } 743 #endif /*ARM64 || RV64*/ 744 745 void ta_elf_relocate(struct ta_elf *elf) 746 { 747 size_t n = 0; 748 749 if (elf->is_32bit) { 750 Elf32_Shdr *shdr = elf->shdr; 751 752 for (n = 0; n < elf->e_shnum; n++) 753 if (shdr[n].sh_type == SHT_REL) 754 e32_relocate(elf, n); 755 } else { 756 Elf64_Shdr *shdr = elf->shdr; 757 758 for (n = 0; n < elf->e_shnum; n++) 759 if (shdr[n].sh_type == SHT_RELA) 760 e64_relocate(elf, n); 761 762 } 763 } 764