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