xref: /optee_os/lib/libutils/ext/include/asan.h (revision b8a0c52c847baf133e08f19f69759eb8a5de1a2c)
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 #ifndef __ASSEMBLER__
18 #include <compiler.h>
19 #include <string.h>
20 #include <types_ext.h>
21 
22 #define ASAN_VA_REGS_MAX 32
23 
24 enum asan_va_reg_type {
25 	ASAN_REG_NO_TYPE,
26 	ASAN_REG_STACK,
27 	ASAN_REG_MEM_POOL,
28 	ASAN_REG_ELF
29 };
30 
31 /* Represents memory mapped region */
32 struct asan_va_reg {
33 	vaddr_t lo;
34 	vaddr_t hi;
35 };
36 
37 /* Global structure with ASan metadata */
38 struct asan_global_info {
39 	/* Virtual memory regions allowed for ASan checks */
40 	size_t regs_count;
41 	struct asan_va_reg regs[ASAN_VA_REGS_MAX];
42 	enum asan_va_reg_type type[ASAN_VA_REGS_MAX];
43 	/* Shadow memory regions */
44 	size_t s_regs_count;
45 	struct asan_va_reg s_regs[ASAN_VA_REGS_MAX];
46 };
47 
48 #ifdef __KERNEL__
49 #define GET_ASAN_INFO() (&__asan_global_info)
50 #else
51 #define GET_ASAN_INFO() ((struct asan_global_info *) \
52 	(CFG_USER_ASAN_SHADOW_OFFSET - SMALL_PAGE_SIZE))
53 #endif
54 
55 #if ((!defined(__KERNEL__) && !defined(__LDELF__)) && \
56      defined(CFG_TA_SANITIZE_KADDRESS)) || \
57 	((defined(__KERNEL__) || defined(__LDELF__)) && \
58 	 defined(CFG_CORE_SANITIZE_KADDRESS))
59 #define ASAN_IS_ENABLED 1
60 #else
61 #define ASAN_IS_ENABLED 0
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
82 static inline void asan_tag_no_access(const void *begin __unused,
83 				      const void *end __unused)
84 {
85 }
86 static inline void asan_tag_access(const void *begin __unused,
87 				   const void *end __unused)
88 {
89 }
90 static inline void asan_tag_heap_free(const void *begin __unused,
91 				      const void *end __unused)
92 {
93 }
94 
95 static inline void *asan_memset_unchecked(void *s, int c, size_t n)
96 {
97 	return memset(s, c, n);
98 }
99 
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 
106 static inline void asan_start(void)
107 {
108 }
109 
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