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 if (st_value > (elf->max_addr - elf->load_addr)) 61 err(TEE_ERROR_BAD_FORMAT, "Symbol location out of range"); 62 63 switch (st_type) { 64 case STT_NOTYPE: 65 case STT_OBJECT: 66 case STT_FUNC: 67 *val = st_value + elf->load_addr; 68 break; 69 default: 70 err(TEE_ERROR_NOT_SUPPORTED, "Symbol type not supported"); 71 } 72 73 return true; 74 } 75 76 static TEE_Result resolve_sym_helper(uint32_t hash, const char *name, 77 vaddr_t *val, struct ta_elf *elf, 78 bool weak_ok) 79 { 80 /* 81 * Using uint32_t here for convenience because both Elf64_Word 82 * and Elf32_Word are 32-bit types 83 */ 84 uint32_t *hashtab = elf->hashtab; 85 uint32_t nbuckets = hashtab[0]; 86 uint32_t nchains = hashtab[1]; 87 uint32_t *bucket = &hashtab[2]; 88 uint32_t *chain = &bucket[nbuckets]; 89 size_t n = 0; 90 91 if (elf->is_32bit) { 92 Elf32_Sym *sym = elf->dynsymtab; 93 94 for (n = bucket[hash % nbuckets]; n; n = chain[n]) { 95 if (n >= nchains || n >= elf->num_dynsyms) 96 err(TEE_ERROR_BAD_FORMAT, 97 "Index out of range"); 98 /* 99 * We're loading values from sym[] which later 100 * will be used to load something. 101 * => Spectre V1 pattern, need to cap the index 102 * against speculation. 103 */ 104 n = confine_array_index(n, elf->num_dynsyms); 105 if (__resolve_sym(elf, 106 ELF32_ST_BIND(sym[n].st_info), 107 ELF32_ST_TYPE(sym[n].st_info), 108 sym[n].st_shndx, 109 sym[n].st_name, 110 sym[n].st_value, name, val, weak_ok)) 111 return TEE_SUCCESS; 112 } 113 } else { 114 Elf64_Sym *sym = elf->dynsymtab; 115 116 for (n = bucket[hash % nbuckets]; n; n = chain[n]) { 117 if (n >= nchains || n >= elf->num_dynsyms) 118 err(TEE_ERROR_BAD_FORMAT, 119 "Index out of range"); 120 /* 121 * We're loading values from sym[] which later 122 * will be used to load something. 123 * => Spectre V1 pattern, need to cap the index 124 * against speculation. 125 */ 126 n = confine_array_index(n, elf->num_dynsyms); 127 if (__resolve_sym(elf, 128 ELF64_ST_BIND(sym[n].st_info), 129 ELF64_ST_TYPE(sym[n].st_info), 130 sym[n].st_shndx, 131 sym[n].st_name, 132 sym[n].st_value, name, val, weak_ok)) 133 return TEE_SUCCESS; 134 } 135 } 136 137 return TEE_ERROR_ITEM_NOT_FOUND; 138 } 139 140 /* 141 * Look for named symbol in @elf, or all modules if @elf == NULL. Global symbols 142 * are searched first, then weak ones. Last option, when at least one weak but 143 * undefined symbol exists, resolve to zero. Otherwise return 144 * TEE_ERROR_ITEM_NOT_FOUND. 145 */ 146 TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val, 147 struct ta_elf *elf) 148 { 149 uint32_t hash = elf_hash(name); 150 151 if (elf) { 152 /* Search global symbols */ 153 if (!resolve_sym_helper(hash, name, val, elf, 154 false /* !weak_ok */)) 155 return TEE_SUCCESS; 156 /* Search weak symbols */ 157 if (!resolve_sym_helper(hash, name, val, elf, 158 true /* weak_ok */)) 159 return TEE_SUCCESS; 160 } 161 162 TAILQ_FOREACH(elf, &main_elf_queue, link) { 163 if (!resolve_sym_helper(hash, name, val, elf, 164 false /* !weak_ok */)) 165 return TEE_SUCCESS; 166 if (!resolve_sym_helper(hash, name, val, elf, 167 true /* weak_ok */)) 168 return TEE_SUCCESS; 169 } 170 171 return TEE_ERROR_ITEM_NOT_FOUND; 172 } 173 174 static void resolve_sym(const char *name, vaddr_t *val) 175 { 176 TEE_Result res = ta_elf_resolve_sym(name, val, NULL); 177 178 if (res) 179 err(res, "Symbol %s not found", name); 180 } 181 182 static void e32_process_dyn_rel(const Elf32_Sym *sym_tab, size_t num_syms, 183 const char *str_tab, size_t str_tab_size, 184 Elf32_Rel *rel, Elf32_Addr *where) 185 { 186 size_t sym_idx = 0; 187 const char *name = NULL; 188 vaddr_t val = 0; 189 size_t name_idx = 0; 190 191 sym_idx = ELF32_R_SYM(rel->r_info); 192 if (sym_idx >= num_syms) 193 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 194 sym_idx = confine_array_index(sym_idx, num_syms); 195 196 name_idx = sym_tab[sym_idx].st_name; 197 if (name_idx >= str_tab_size) 198 err(TEE_ERROR_BAD_FORMAT, "Name index out of range"); 199 name = str_tab + name_idx; 200 201 resolve_sym(name, &val); 202 *where = val; 203 } 204 205 static void e32_relocate(struct ta_elf *elf, unsigned int rel_sidx) 206 { 207 Elf32_Shdr *shdr = elf->shdr; 208 Elf32_Rel *rel = NULL; 209 Elf32_Rel *rel_end = NULL; 210 size_t sym_tab_idx = 0; 211 Elf32_Sym *sym_tab = NULL; 212 size_t num_syms = 0; 213 size_t sh_end = 0; 214 const char *str_tab = NULL; 215 size_t str_tab_size = 0; 216 217 assert(shdr[rel_sidx].sh_type == SHT_REL); 218 219 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf32_Rel)); 220 221 sym_tab_idx = shdr[rel_sidx].sh_link; 222 if (sym_tab_idx) { 223 size_t str_tab_idx = 0; 224 225 if (sym_tab_idx >= elf->e_shnum) 226 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range"); 227 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum); 228 229 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf32_Sym)); 230 231 /* Check the address is inside ELF memory */ 232 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 233 shdr[sym_tab_idx].sh_size, &sh_end)) 234 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 235 if (sh_end >= (elf->max_addr - elf->load_addr)) 236 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range"); 237 238 sym_tab = (Elf32_Sym *)(elf->load_addr + 239 shdr[sym_tab_idx].sh_addr); 240 241 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf32_Sym); 242 243 str_tab_idx = shdr[sym_tab_idx].sh_link; 244 if (str_tab_idx) { 245 if (str_tab_idx >= elf->e_shnum) 246 err(TEE_ERROR_BAD_FORMAT, 247 "STRTAB index out of range"); 248 str_tab_idx = confine_array_index(str_tab_idx, 249 elf->e_shnum); 250 251 /* Check the address is inside ELF memory */ 252 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 253 shdr[str_tab_idx].sh_size, &sh_end)) 254 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 255 if (sh_end >= (elf->max_addr - elf->load_addr)) 256 err(TEE_ERROR_BAD_FORMAT, 257 "STRTAB out of range"); 258 259 str_tab = (const char *)(elf->load_addr + 260 shdr[str_tab_idx].sh_addr); 261 str_tab_size = shdr[str_tab_idx].sh_size; 262 } 263 } 264 265 /* Check the address is inside TA memory */ 266 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, 267 shdr[rel_sidx].sh_size, &sh_end)) 268 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 269 if (sh_end >= (elf->max_addr - elf->load_addr)) 270 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range"); 271 rel = (Elf32_Rel *)(elf->load_addr + shdr[rel_sidx].sh_addr); 272 273 rel_end = rel + shdr[rel_sidx].sh_size / sizeof(Elf32_Rel); 274 for (; rel < rel_end; rel++) { 275 Elf32_Addr *where = NULL; 276 size_t sym_idx = 0; 277 278 /* Check the address is inside TA memory */ 279 if (rel->r_offset >= (elf->max_addr - elf->load_addr)) 280 err(TEE_ERROR_BAD_FORMAT, 281 "Relocation offset out of range"); 282 where = (Elf32_Addr *)(elf->load_addr + rel->r_offset); 283 284 switch (ELF32_R_TYPE(rel->r_info)) { 285 case R_ARM_ABS32: 286 sym_idx = ELF32_R_SYM(rel->r_info); 287 if (sym_idx >= num_syms) 288 err(TEE_ERROR_BAD_FORMAT, 289 "Symbol index out of range"); 290 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 291 /* Symbol is external */ 292 e32_process_dyn_rel(sym_tab, num_syms, str_tab, 293 str_tab_size, rel, where); 294 } else { 295 *where += elf->load_addr + 296 sym_tab[sym_idx].st_value; 297 } 298 break; 299 case R_ARM_REL32: 300 sym_idx = ELF32_R_SYM(rel->r_info); 301 if (sym_idx >= num_syms) 302 err(TEE_ERROR_BAD_FORMAT, 303 "Symbol index out of range"); 304 *where += sym_tab[sym_idx].st_value - rel->r_offset; 305 break; 306 case R_ARM_RELATIVE: 307 *where += elf->load_addr; 308 break; 309 case R_ARM_GLOB_DAT: 310 case R_ARM_JUMP_SLOT: 311 e32_process_dyn_rel(sym_tab, num_syms, str_tab, 312 str_tab_size, rel, where); 313 break; 314 default: 315 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %d", 316 ELF32_R_TYPE(rel->r_info)); 317 } 318 } 319 } 320 321 #ifdef ARM64 322 static void e64_process_dyn_rela(const Elf64_Sym *sym_tab, size_t num_syms, 323 const char *str_tab, size_t str_tab_size, 324 Elf64_Rela *rela, Elf64_Addr *where) 325 { 326 size_t sym_idx = 0; 327 const char *name = NULL; 328 uintptr_t val = 0; 329 size_t name_idx = 0; 330 331 sym_idx = ELF64_R_SYM(rela->r_info); 332 if (sym_idx >= num_syms) 333 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 334 sym_idx = confine_array_index(sym_idx, num_syms); 335 336 name_idx = sym_tab[sym_idx].st_name; 337 if (name_idx >= str_tab_size) 338 err(TEE_ERROR_BAD_FORMAT, "Name index out of range"); 339 name = str_tab + name_idx; 340 341 resolve_sym(name, &val); 342 *where = val; 343 } 344 345 static void e64_relocate(struct ta_elf *elf, unsigned int rel_sidx) 346 { 347 Elf64_Shdr *shdr = elf->shdr; 348 Elf64_Rela *rela = NULL; 349 Elf64_Rela *rela_end = NULL; 350 size_t sym_tab_idx = 0; 351 Elf64_Sym *sym_tab = NULL; 352 size_t num_syms = 0; 353 size_t sh_end = 0; 354 const char *str_tab = NULL; 355 size_t str_tab_size = 0; 356 357 assert(shdr[rel_sidx].sh_type == SHT_RELA); 358 359 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf64_Rela)); 360 361 sym_tab_idx = shdr[rel_sidx].sh_link; 362 if (sym_tab_idx) { 363 size_t str_tab_idx = 0; 364 365 if (sym_tab_idx >= elf->e_shnum) 366 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range"); 367 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum); 368 369 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf64_Sym)); 370 371 /* Check the address is inside TA memory */ 372 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 373 shdr[sym_tab_idx].sh_size, &sh_end)) 374 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 375 if (sh_end >= (elf->max_addr - elf->load_addr)) 376 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range"); 377 378 sym_tab = (Elf64_Sym *)(elf->load_addr + 379 shdr[sym_tab_idx].sh_addr); 380 381 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf64_Sym); 382 383 str_tab_idx = shdr[sym_tab_idx].sh_link; 384 if (str_tab_idx) { 385 if (str_tab_idx >= elf->e_shnum) 386 err(TEE_ERROR_BAD_FORMAT, 387 "STRTAB index out of range"); 388 str_tab_idx = confine_array_index(str_tab_idx, 389 elf->e_shnum); 390 391 /* Check the address is inside ELF memory */ 392 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 393 shdr[str_tab_idx].sh_size, &sh_end)) 394 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 395 if (sh_end >= (elf->max_addr - elf->load_addr)) 396 err(TEE_ERROR_BAD_FORMAT, 397 "STRTAB out of range"); 398 399 str_tab = (const char *)(elf->load_addr + 400 shdr[str_tab_idx].sh_addr); 401 str_tab_size = shdr[str_tab_idx].sh_size; 402 } 403 } 404 405 /* Check the address is inside TA memory */ 406 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, 407 shdr[rel_sidx].sh_size, &sh_end)) 408 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 409 if (sh_end >= (elf->max_addr - elf->load_addr)) 410 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range"); 411 rela = (Elf64_Rela *)(elf->load_addr + shdr[rel_sidx].sh_addr); 412 413 rela_end = rela + shdr[rel_sidx].sh_size / sizeof(Elf64_Rela); 414 for (; rela < rela_end; rela++) { 415 Elf64_Addr *where = NULL; 416 size_t sym_idx = 0; 417 418 /* Check the address is inside TA memory */ 419 if (rela->r_offset >= (elf->max_addr - elf->load_addr)) 420 err(TEE_ERROR_BAD_FORMAT, 421 "Relocation offset out of range"); 422 423 where = (Elf64_Addr *)(elf->load_addr + rela->r_offset); 424 425 switch (ELF64_R_TYPE(rela->r_info)) { 426 case R_AARCH64_ABS64: 427 sym_idx = ELF64_R_SYM(rela->r_info); 428 if (sym_idx >= num_syms) 429 err(TEE_ERROR_BAD_FORMAT, 430 "Symbol index out of range"); 431 sym_idx = confine_array_index(sym_idx, num_syms); 432 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 433 /* Symbol is external */ 434 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 435 str_tab_size, rela, where); 436 } else { 437 *where = rela->r_addend + elf->load_addr + 438 sym_tab[sym_idx].st_value; 439 } 440 break; 441 case R_AARCH64_RELATIVE: 442 *where = rela->r_addend + elf->load_addr; 443 break; 444 case R_AARCH64_GLOB_DAT: 445 case R_AARCH64_JUMP_SLOT: 446 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 447 str_tab_size, rela, where); 448 break; 449 default: 450 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %zd", 451 ELF64_R_TYPE(rela->r_info)); 452 } 453 } 454 } 455 #else /*ARM64*/ 456 static void __noreturn e64_relocate(struct ta_elf *elf __unused, 457 unsigned int rel_sidx __unused) 458 { 459 err(TEE_ERROR_NOT_SUPPORTED, "arm64 not supported"); 460 } 461 #endif /*ARM64*/ 462 463 void ta_elf_relocate(struct ta_elf *elf) 464 { 465 size_t n = 0; 466 467 if (elf->is_32bit) { 468 Elf32_Shdr *shdr = elf->shdr; 469 470 for (n = 0; n < elf->e_shnum; n++) 471 if (shdr[n].sh_type == SHT_REL) 472 e32_relocate(elf, n); 473 } else { 474 Elf64_Shdr *shdr = elf->shdr; 475 476 for (n = 0; n < elf->e_shnum; n++) 477 if (shdr[n].sh_type == SHT_RELA) 478 e64_relocate(elf, n); 479 480 } 481 } 482