xref: /optee_os/lib/libutils/ext/include/asan.h (revision 36e34afe9e4d78e84977d2b5de867c6e2cb6b514)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2016, Linaro Limited
4  */
5 #ifndef __ASAN_H
6 #define __ASAN_H
7 
8 #include <stdint.h>
9 
10 #define ASAN_DATA_RED_ZONE	-1
11 #define ASAN_HEAP_RED_ZONE	-2
12 
13 #define ASAN_BLOCK_SIZE		U(8)
14 #define ASAN_BLOCK_SHIFT	U(3)
15 #define ASAN_BLOCK_MASK		(ASAN_BLOCK_SIZE - 1)
16 
17 #if ((!defined(__KERNEL__) && !defined(__LDELF__)) && \
18      defined(CFG_TA_SANITIZE_KADDRESS)) || \
19 	((defined(__KERNEL__) || defined(__LDELF__)) && \
20 	 defined(CFG_CORE_SANITIZE_KADDRESS))
21 #define ASAN_IS_ENABLED 1
22 #else
23 #define ASAN_IS_ENABLED 0
24 #endif
25 
26 #ifndef __ASSEMBLER__
27 #include <compiler.h>
28 #include <string.h>
29 #include <types_ext.h>
30 
31 #define ASAN_VA_REGS_MAX 32
32 
33 enum asan_va_reg_type {
34 	ASAN_REG_NO_TYPE,
35 	ASAN_REG_STACK,
36 	ASAN_REG_MEM_POOL,
37 	ASAN_REG_ELF
38 };
39 
40 /* Represents memory mapped region */
41 struct asan_va_reg {
42 	vaddr_t lo;
43 	vaddr_t hi;
44 };
45 
46 /* Global structure with ASan metadata */
47 struct asan_global_info {
48 	/* Virtual memory regions allowed for ASan checks */
49 	size_t regs_count;
50 	struct asan_va_reg regs[ASAN_VA_REGS_MAX];
51 	enum asan_va_reg_type type[ASAN_VA_REGS_MAX];
52 	/* Shadow memory regions */
53 	size_t s_regs_count;
54 	struct asan_va_reg s_regs[ASAN_VA_REGS_MAX];
55 };
56 
57 #ifdef __KERNEL__
58 #define GET_ASAN_INFO() (&__asan_global_info)
59 #else
60 #define GET_ASAN_INFO() ((struct asan_global_info *) \
61 	(CFG_USER_ASAN_SHADOW_OFFSET - SMALL_PAGE_SIZE))
62 #endif
63 
64 #if ASAN_IS_ENABLED
65 /* ASAN enabled */
66 typedef void (*asan_panic_cb_t)(void);
67 
68 void asan_add_shadowed(const void *va_begin, const void *va_end,
69 		       enum asan_va_reg_type type);
70 void asan_start(void);
71 void asan_panic(void);
72 void asan_set_panic_cb(asan_panic_cb_t panic_cb);
73 
74 void asan_tag_no_access(const void *begin, const void *end);
75 void asan_tag_access(const void *begin, const void *end);
76 void asan_tag_heap_free(const void *begin, const void *end);
77 void *asan_memset_unchecked(void *s, int c, size_t n);
78 void *asan_memcpy_unchecked(void *__restrict s1, const void *__restrict s2,
79 			    size_t n);
80 int asan_user_map_shadow(void *lo, void *hi, enum asan_va_reg_type type);
81 #else
asan_tag_no_access(const void * begin __unused,const void * end __unused)82 static inline void asan_tag_no_access(const void *begin __unused,
83 				      const void *end __unused)
84 {
85 }
asan_tag_access(const void * begin __unused,const void * end __unused)86 static inline void asan_tag_access(const void *begin __unused,
87 				   const void *end __unused)
88 {
89 }
asan_tag_heap_free(const void * begin __unused,const void * end __unused)90 static inline void asan_tag_heap_free(const void *begin __unused,
91 				      const void *end __unused)
92 {
93 }
94 
asan_memset_unchecked(void * s,int c,size_t n)95 static inline void *asan_memset_unchecked(void *s, int c, size_t n)
96 {
97 	return memset(s, c, n);
98 }
99 
asan_memcpy_unchecked(void * __restrict s1,const void * __restrict s2,size_t n)100 static inline void *asan_memcpy_unchecked(void *__restrict s1,
101 					  const void *__restrict s2, size_t n)
102 {
103 	return memcpy(s1, s2, n);
104 }
105 
asan_start(void)106 static inline void asan_start(void)
107 {
108 }
109 
asan_user_map_shadow(void * lo __unused,void * hi __unused,enum asan_va_reg_type type __unused)110 static inline int asan_user_map_shadow(void *lo __unused, void *hi __unused,
111 				       enum asan_va_reg_type type __unused)
112 {
113 	return 0;
114 }
115 #endif /* ASAN_IS_ENABLED */
116 
117 #endif /*__ASSEMBLER__*/
118 #endif /*__ASAN_H*/
119