xref: /optee_os/ldelf/asan.c (revision b8a0c52c847baf133e08f19f69759eb8a5de1a2c)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2026, Linutronix GmbH
4  */
5 
6 #include <compiler.h>
7 #include <ldelf.h>
8 
9 #include "asan.h"
10 #include "sys.h"
11 
init_run_constructors(void)12 static void init_run_constructors(void)
13 {
14 	const vaddr_t *ctor = NULL;
15 
16 	for (ctor = &__init_array_start; ctor < &__init_array_end; ctor++)
17 		((void (*)(void))(*ctor))();
18 }
19 
asan_ldelf_map_stack(size_t size)20 static int asan_ldelf_map_stack(size_t size)
21 {
22 	vaddr_t stack_top = (vaddr_t)&stack_top;
23 	vaddr_t stack_base = 0;
24 
25 	size = ROUNDUP(size, SMALL_PAGE_SIZE);
26 	stack_top = ROUNDUP(stack_top, SMALL_PAGE_SIZE);
27 	stack_base = stack_top - size;
28 
29 	return asan_user_map_shadow((void *)stack_base, (void *)stack_top,
30 				    ASAN_REG_STACK);
31 }
32 
asan_init_ldelf(void)33 TEE_Result asan_init_ldelf(void)
34 {
35 	vaddr_t req = (vaddr_t)GET_ASAN_INFO();
36 	TEE_Result rc = TEE_SUCCESS;
37 	vaddr_t tmp = req;
38 
39 	/* Map global ASan info */
40 	rc = sys_map_zi(sizeof(struct asan_global_info), 0, &tmp, 0, 0);
41 	if (rc == TEE_SUCCESS && req == tmp) {
42 		/* Map shadow stack for ldelf */
43 		rc = asan_ldelf_map_stack(LDELF_STACK_SIZE);
44 		if (rc) {
45 			EMSG("failed to map ldelf shadow stack");
46 			panic();
47 		}
48 		/* Map shadow memory for ldelf binary sections */
49 		rc = asan_user_map_shadow((void *)__text_start,
50 					  (void *)ROUNDUP((vaddr_t)__end,
51 					  SMALL_PAGE_SIZE),
52 					  ASAN_REG_ELF);
53 		if (rc) {
54 			EMSG("failed to map ldelf shadow elf sections");
55 			panic();
56 		}
57 		/* Register global ASan constructors */
58 		init_run_constructors();
59 	} else {
60 		rc = TEE_ERROR_GENERIC;
61 	}
62 
63 	return rc;
64 }
65