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 
elf_hash(const char * name)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 
__resolve_sym(struct ta_elf * elf,unsigned int st_bind,unsigned int st_type,size_t st_shndx,size_t st_name,size_t st_value,const char * name,vaddr_t * val,bool weak_ok)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 
resolve_sym_helper(uint32_t hash,const char * name,vaddr_t * val,struct ta_elf * elf,bool weak_ok)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  */
ta_elf_resolve_sym(const char * name,vaddr_t * val,struct ta_elf ** found_elf,struct ta_elf * elf)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 
e32_get_sym_name(const Elf32_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf32_Rel * rel,const char ** name)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 
resolve_sym(const char * name,vaddr_t * val,struct ta_elf ** mod)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 
e32_process_dyn_rel(const Elf32_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf32_Rel * rel,Elf32_Addr * where)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 
e32_tls_get_module(const Elf32_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf32_Rel * rel,struct ta_elf ** mod)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 
e32_tls_resolve(const Elf32_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf32_Rel * rel,vaddr_t * val)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 
e32_relocate(struct ta_elf * elf,unsigned int rel_sidx)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_NONE:
338 			/*
339 			 * One would expect linker prevents such useless entry
340 			 * in the relocation table. We still handle this type
341 			 * here in case such entries exist.
342 			 */
343 			break;
344 		case R_ARM_ABS32:
345 			sym_idx = ELF32_R_SYM(rel->r_info);
346 			if (sym_idx >= num_syms)
347 				err(TEE_ERROR_BAD_FORMAT,
348 				    "Symbol index out of range");
349 			if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) {
350 				/* Symbol is external */
351 				e32_process_dyn_rel(sym_tab, num_syms, str_tab,
352 						    str_tab_size, rel, where);
353 			} else {
354 				*where += elf->load_addr +
355 					  sym_tab[sym_idx].st_value;
356 			}
357 			break;
358 		case R_ARM_REL32:
359 			sym_idx = ELF32_R_SYM(rel->r_info);
360 			if (sym_idx >= num_syms)
361 				err(TEE_ERROR_BAD_FORMAT,
362 				    "Symbol index out of range");
363 			*where += sym_tab[sym_idx].st_value - rel->r_offset;
364 			break;
365 		case R_ARM_RELATIVE:
366 			*where += elf->load_addr;
367 			break;
368 		case R_ARM_GLOB_DAT:
369 		case R_ARM_JUMP_SLOT:
370 			if (!sym_tab)
371 				err(TEE_ERROR_BAD_FORMAT,
372 				    "Missing symbol table");
373 			e32_process_dyn_rel(sym_tab, num_syms, str_tab,
374 					    str_tab_size, rel, where);
375 			break;
376 		case R_ARM_TLS_DTPMOD32:
377 			if (!sym_tab)
378 				err(TEE_ERROR_BAD_FORMAT,
379 				    "Missing symbol table");
380 			mod = elf;
381 			e32_tls_get_module(sym_tab, num_syms, str_tab,
382 					   str_tab_size, rel, &mod);
383 			*where = mod->tls_mod_id;
384 			break;
385 		case R_ARM_TLS_DTPOFF32:
386 			if (!sym_tab)
387 				err(TEE_ERROR_BAD_FORMAT,
388 				    "Missing symbol table");
389 			e32_tls_resolve(sym_tab, num_syms, str_tab,
390 					str_tab_size, rel, &val);
391 			*where = val;
392 			break;
393 		default:
394 			err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %d",
395 			     ELF32_R_TYPE(rel->r_info));
396 		}
397 	}
398 }
399 
400 #ifdef ARM64
e64_get_sym_name(const Elf64_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf64_Rela * rela,const char ** name)401 static void e64_get_sym_name(const Elf64_Sym *sym_tab, size_t num_syms,
402 			     const char *str_tab, size_t str_tab_size,
403 			     Elf64_Rela *rela, const char **name)
404 {
405 	size_t sym_idx = 0;
406 	size_t name_idx = 0;
407 
408 	sym_idx = ELF64_R_SYM(rela->r_info);
409 	if (sym_idx >= num_syms)
410 		err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range");
411 	sym_idx = confine_array_index(sym_idx, num_syms);
412 
413 	name_idx = sym_tab[sym_idx].st_name;
414 	if (name_idx >= str_tab_size)
415 		err(TEE_ERROR_BAD_FORMAT, "Name index out of range");
416 	*name = str_tab + name_idx;
417 }
418 
e64_process_dyn_rela(const Elf64_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf64_Rela * rela,Elf64_Addr * where)419 static void e64_process_dyn_rela(const Elf64_Sym *sym_tab, size_t num_syms,
420 				 const char *str_tab, size_t str_tab_size,
421 				 Elf64_Rela *rela, Elf64_Addr *where)
422 {
423 	const char *name = NULL;
424 	uintptr_t val = 0;
425 
426 	e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, &name);
427 	resolve_sym(name, &val, NULL);
428 	*where = val;
429 }
430 
e64_process_tls_tprel_rela(const Elf64_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf64_Rela * rela,Elf64_Addr * where,struct ta_elf * elf)431 static void e64_process_tls_tprel_rela(const Elf64_Sym *sym_tab,
432 				       size_t num_syms, const char *str_tab,
433 				       size_t str_tab_size, Elf64_Rela *rela,
434 				       Elf64_Addr *where, struct ta_elf *elf)
435 {
436 	struct ta_elf *mod = NULL;
437 	const char *name = NULL;
438 	size_t sym_idx = 0;
439 	vaddr_t symval = 0;
440 
441 	sym_idx = ELF64_R_SYM(rela->r_info);
442 	if (sym_idx) {
443 		e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela,
444 				 &name);
445 		resolve_sym(name, &symval, &mod);
446 	} else {
447 		mod = elf;
448 	}
449 	*where = symval + mod->tls_tcb_offs + rela->r_addend;
450 }
451 
452 struct tlsdesc {
453 	long (*resolver)(struct tlsdesc *td);
454 	long value;
455 };
456 
457 /* Helper function written in assembly due to the calling convention */
458 long tlsdesc_resolve(struct tlsdesc *td);
459 
e64_process_tlsdesc_rela(const Elf64_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf64_Rela * rela,Elf64_Addr * where,struct ta_elf * elf)460 static void e64_process_tlsdesc_rela(const Elf64_Sym *sym_tab, size_t num_syms,
461 				     const char *str_tab, size_t str_tab_size,
462 				     Elf64_Rela *rela, Elf64_Addr *where,
463 				     struct ta_elf *elf)
464 {
465 	/*
466 	 * @where points to a pair of 64-bit words in the GOT or PLT which is
467 	 * mapped to a struct tlsdesc:
468 	 *
469 	 * - resolver() must return the offset of the thread-local variable
470 	 *   relative to TPIDR_EL0.
471 	 * - value is implementation-dependent. The TLS_TPREL handling code is
472 	 *   re-used to get the desired offset so that tlsdesc_resolve() just
473 	 *   needs to return this value.
474 	 *
475 	 * Both the TA and ldelf are AArch64 so it is OK to point to a function
476 	 * in ldelf.
477 	 */
478 	*where = (Elf64_Addr)tlsdesc_resolve;
479 	e64_process_tls_tprel_rela(sym_tab, num_syms, str_tab, str_tab_size,
480 				   rela, where + 1, elf);
481 }
482 
e64_relocate(struct ta_elf * elf,unsigned int rel_sidx)483 static void e64_relocate(struct ta_elf *elf, unsigned int rel_sidx)
484 {
485 	Elf64_Shdr *shdr = elf->shdr;
486 	Elf64_Rela *rela = NULL;
487 	Elf64_Rela *rela_end = NULL;
488 	size_t sym_tab_idx = 0;
489 	Elf64_Sym *sym_tab = NULL;
490 	size_t num_syms = 0;
491 	size_t sh_end = 0;
492 	const char *str_tab = NULL;
493 	size_t str_tab_size = 0;
494 
495 	assert(shdr[rel_sidx].sh_type == SHT_RELA);
496 
497 	assert(shdr[rel_sidx].sh_entsize == sizeof(Elf64_Rela));
498 
499 	sym_tab_idx = shdr[rel_sidx].sh_link;
500 	if (sym_tab_idx) {
501 		size_t str_tab_idx = 0;
502 
503 		if (sym_tab_idx >= elf->e_shnum)
504 			err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range");
505 		sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum);
506 
507 		assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf64_Sym));
508 
509 		/* Check the address is inside TA memory */
510 		if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr,
511 				 shdr[sym_tab_idx].sh_size, &sh_end))
512 			err(TEE_ERROR_BAD_FORMAT, "Overflow");
513 		if (sh_end >= (elf->max_addr - elf->load_addr))
514 			err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range");
515 
516 		sym_tab = (Elf64_Sym *)(elf->load_addr +
517 					shdr[sym_tab_idx].sh_addr);
518 
519 		num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf64_Sym);
520 
521 		str_tab_idx = shdr[sym_tab_idx].sh_link;
522 		if (str_tab_idx) {
523 			if (str_tab_idx >= elf->e_shnum)
524 				err(TEE_ERROR_BAD_FORMAT,
525 				    "STRTAB index out of range");
526 			str_tab_idx = confine_array_index(str_tab_idx,
527 							  elf->e_shnum);
528 
529 			/* Check the address is inside ELF memory */
530 			if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr,
531 					 shdr[str_tab_idx].sh_size, &sh_end))
532 				err(TEE_ERROR_BAD_FORMAT, "Overflow");
533 			if (sh_end >= (elf->max_addr - elf->load_addr))
534 				err(TEE_ERROR_BAD_FORMAT,
535 				    "STRTAB out of range");
536 
537 			str_tab = (const char *)(elf->load_addr +
538 						 shdr[str_tab_idx].sh_addr);
539 			str_tab_size = shdr[str_tab_idx].sh_size;
540 		}
541 	}
542 
543 	/* Check the address is inside TA memory */
544 	if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr,
545 			 shdr[rel_sidx].sh_size, &sh_end))
546 		err(TEE_ERROR_BAD_FORMAT, "Overflow");
547 	if (sh_end >= (elf->max_addr - elf->load_addr))
548 		err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range");
549 	rela = (Elf64_Rela *)(elf->load_addr + shdr[rel_sidx].sh_addr);
550 
551 	rela_end = rela + shdr[rel_sidx].sh_size / sizeof(Elf64_Rela);
552 	for (; rela < rela_end; rela++) {
553 		Elf64_Addr *where = NULL;
554 		size_t sym_idx = 0;
555 
556 		/* Check the address is inside TA memory */
557 		if (rela->r_offset >= (elf->max_addr - elf->load_addr))
558 			err(TEE_ERROR_BAD_FORMAT,
559 			    "Relocation offset out of range");
560 
561 		where = (Elf64_Addr *)(elf->load_addr + rela->r_offset);
562 
563 		switch (ELF64_R_TYPE(rela->r_info)) {
564 		case R_AARCH64_NONE:
565 			/*
566 			 * One would expect linker prevents such useless entry
567 			 * in the relocation table. We still handle this type
568 			 * here in case such entries exist.
569 			 */
570 			break;
571 		case R_AARCH64_ABS64:
572 			sym_idx = ELF64_R_SYM(rela->r_info);
573 			if (sym_idx >= num_syms)
574 				err(TEE_ERROR_BAD_FORMAT,
575 				    "Symbol index out of range");
576 			sym_idx = confine_array_index(sym_idx, num_syms);
577 			if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) {
578 				/* Symbol is external */
579 				e64_process_dyn_rela(sym_tab, num_syms, str_tab,
580 						     str_tab_size, rela, where);
581 			} else {
582 				*where = rela->r_addend + elf->load_addr +
583 					 sym_tab[sym_idx].st_value;
584 			}
585 			break;
586 		case R_AARCH64_RELATIVE:
587 			*where = rela->r_addend + elf->load_addr;
588 			break;
589 		case R_AARCH64_GLOB_DAT:
590 		case R_AARCH64_JUMP_SLOT:
591 			e64_process_dyn_rela(sym_tab, num_syms, str_tab,
592 					     str_tab_size, rela, where);
593 			break;
594 		case R_AARCH64_TLS_TPREL:
595 			e64_process_tls_tprel_rela(sym_tab, num_syms, str_tab,
596 						   str_tab_size, rela, where,
597 						   elf);
598 			break;
599 		case R_AARCH64_TLSDESC:
600 			e64_process_tlsdesc_rela(sym_tab, num_syms, str_tab,
601 						 str_tab_size, rela, where,
602 						 elf);
603 			break;
604 		default:
605 			err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %zd",
606 			     ELF64_R_TYPE(rela->r_info));
607 		}
608 	}
609 }
610 #else /*ARM64*/
e64_relocate(struct ta_elf * elf __unused,unsigned int rel_sidx __unused)611 static void __noreturn e64_relocate(struct ta_elf *elf __unused,
612 				    unsigned int rel_sidx __unused)
613 {
614 	err(TEE_ERROR_NOT_SUPPORTED, "arm64 not supported");
615 }
616 #endif /*ARM64*/
617 
ta_elf_relocate(struct ta_elf * elf)618 void ta_elf_relocate(struct ta_elf *elf)
619 {
620 	size_t n = 0;
621 
622 	if (elf->is_32bit) {
623 		Elf32_Shdr *shdr = elf->shdr;
624 
625 		for (n = 0; n < elf->e_shnum; n++)
626 			if (shdr[n].sh_type == SHT_REL)
627 				e32_relocate(elf, n);
628 	} else {
629 		Elf64_Shdr *shdr = elf->shdr;
630 
631 		for (n = 0; n < elf->e_shnum; n++)
632 			if (shdr[n].sh_type == SHT_RELA)
633 				e64_relocate(elf, n);
634 
635 	}
636 }
637