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