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