xref: /optee_os/ldelf/asan.c (revision b8a0c52c847baf133e08f19f69759eb8a5de1a2c)
14cafd8a3SAleksandr Iashchenko // SPDX-License-Identifier: BSD-2-Clause
24cafd8a3SAleksandr Iashchenko /*
34cafd8a3SAleksandr Iashchenko  * Copyright (c) 2026, Linutronix GmbH
44cafd8a3SAleksandr Iashchenko  */
54cafd8a3SAleksandr Iashchenko 
64cafd8a3SAleksandr Iashchenko #include <compiler.h>
74cafd8a3SAleksandr Iashchenko #include <ldelf.h>
84cafd8a3SAleksandr Iashchenko 
94cafd8a3SAleksandr Iashchenko #include "asan.h"
104cafd8a3SAleksandr Iashchenko #include "sys.h"
114cafd8a3SAleksandr Iashchenko 
init_run_constructors(void)124cafd8a3SAleksandr Iashchenko static void init_run_constructors(void)
134cafd8a3SAleksandr Iashchenko {
144cafd8a3SAleksandr Iashchenko 	const vaddr_t *ctor = NULL;
154cafd8a3SAleksandr Iashchenko 
164cafd8a3SAleksandr Iashchenko 	for (ctor = &__init_array_start; ctor < &__init_array_end; ctor++)
174cafd8a3SAleksandr Iashchenko 		((void (*)(void))(*ctor))();
184cafd8a3SAleksandr Iashchenko }
194cafd8a3SAleksandr Iashchenko 
asan_ldelf_map_stack(size_t size)204cafd8a3SAleksandr Iashchenko static int asan_ldelf_map_stack(size_t size)
214cafd8a3SAleksandr Iashchenko {
224cafd8a3SAleksandr Iashchenko 	vaddr_t stack_top = (vaddr_t)&stack_top;
234cafd8a3SAleksandr Iashchenko 	vaddr_t stack_base = 0;
244cafd8a3SAleksandr Iashchenko 
254cafd8a3SAleksandr Iashchenko 	size = ROUNDUP(size, SMALL_PAGE_SIZE);
264cafd8a3SAleksandr Iashchenko 	stack_top = ROUNDUP(stack_top, SMALL_PAGE_SIZE);
274cafd8a3SAleksandr Iashchenko 	stack_base = stack_top - size;
284cafd8a3SAleksandr Iashchenko 
29*b8a0c52cSAleksandr Iashchenko 	return asan_user_map_shadow((void *)stack_base, (void *)stack_top,
30*b8a0c52cSAleksandr Iashchenko 				    ASAN_REG_STACK);
314cafd8a3SAleksandr Iashchenko }
324cafd8a3SAleksandr Iashchenko 
asan_init_ldelf(void)334cafd8a3SAleksandr Iashchenko TEE_Result asan_init_ldelf(void)
344cafd8a3SAleksandr Iashchenko {
354cafd8a3SAleksandr Iashchenko 	vaddr_t req = (vaddr_t)GET_ASAN_INFO();
364cafd8a3SAleksandr Iashchenko 	TEE_Result rc = TEE_SUCCESS;
374cafd8a3SAleksandr Iashchenko 	vaddr_t tmp = req;
384cafd8a3SAleksandr Iashchenko 
394cafd8a3SAleksandr Iashchenko 	/* Map global ASan info */
404cafd8a3SAleksandr Iashchenko 	rc = sys_map_zi(sizeof(struct asan_global_info), 0, &tmp, 0, 0);
414cafd8a3SAleksandr Iashchenko 	if (rc == TEE_SUCCESS && req == tmp) {
424cafd8a3SAleksandr Iashchenko 		/* Map shadow stack for ldelf */
434cafd8a3SAleksandr Iashchenko 		rc = asan_ldelf_map_stack(LDELF_STACK_SIZE);
444cafd8a3SAleksandr Iashchenko 		if (rc) {
454cafd8a3SAleksandr Iashchenko 			EMSG("failed to map ldelf shadow stack");
464cafd8a3SAleksandr Iashchenko 			panic();
474cafd8a3SAleksandr Iashchenko 		}
484cafd8a3SAleksandr Iashchenko 		/* Map shadow memory for ldelf binary sections */
494cafd8a3SAleksandr Iashchenko 		rc = asan_user_map_shadow((void *)__text_start,
504cafd8a3SAleksandr Iashchenko 					  (void *)ROUNDUP((vaddr_t)__end,
51*b8a0c52cSAleksandr Iashchenko 					  SMALL_PAGE_SIZE),
52*b8a0c52cSAleksandr Iashchenko 					  ASAN_REG_ELF);
534cafd8a3SAleksandr Iashchenko 		if (rc) {
544cafd8a3SAleksandr Iashchenko 			EMSG("failed to map ldelf shadow elf sections");
554cafd8a3SAleksandr Iashchenko 			panic();
564cafd8a3SAleksandr Iashchenko 		}
574cafd8a3SAleksandr Iashchenko 		/* Register global ASan constructors */
584cafd8a3SAleksandr Iashchenko 		init_run_constructors();
594cafd8a3SAleksandr Iashchenko 	} else {
604cafd8a3SAleksandr Iashchenko 		rc = TEE_ERROR_GENERIC;
614cafd8a3SAleksandr Iashchenko 	}
624cafd8a3SAleksandr Iashchenko 
634cafd8a3SAleksandr Iashchenko 	return rc;
644cafd8a3SAleksandr Iashchenko }
65