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