1d6d1731bSAleksandr Iashchenko /* SPDX-License-Identifier: BSD-2-Clause */
2d6d1731bSAleksandr Iashchenko /*
3d6d1731bSAleksandr Iashchenko * Copyright (c) 2016, Linaro Limited
4d6d1731bSAleksandr Iashchenko */
5d6d1731bSAleksandr Iashchenko #ifndef __ASAN_H
6d6d1731bSAleksandr Iashchenko #define __ASAN_H
7d6d1731bSAleksandr Iashchenko
8d6d1731bSAleksandr Iashchenko #include <stdint.h>
9d6d1731bSAleksandr Iashchenko
10d6d1731bSAleksandr Iashchenko #define ASAN_DATA_RED_ZONE -1
11d6d1731bSAleksandr Iashchenko #define ASAN_HEAP_RED_ZONE -2
12d6d1731bSAleksandr Iashchenko
13d6d1731bSAleksandr Iashchenko #define ASAN_BLOCK_SIZE U(8)
14d6d1731bSAleksandr Iashchenko #define ASAN_BLOCK_SHIFT U(3)
15d6d1731bSAleksandr Iashchenko #define ASAN_BLOCK_MASK (ASAN_BLOCK_SIZE - 1)
16d6d1731bSAleksandr Iashchenko
17*36e34afeSAleksandr Iashchenko #if ((!defined(__KERNEL__) && !defined(__LDELF__)) && \
18*36e34afeSAleksandr Iashchenko defined(CFG_TA_SANITIZE_KADDRESS)) || \
19*36e34afeSAleksandr Iashchenko ((defined(__KERNEL__) || defined(__LDELF__)) && \
20*36e34afeSAleksandr Iashchenko defined(CFG_CORE_SANITIZE_KADDRESS))
21*36e34afeSAleksandr Iashchenko #define ASAN_IS_ENABLED 1
22*36e34afeSAleksandr Iashchenko #else
23*36e34afeSAleksandr Iashchenko #define ASAN_IS_ENABLED 0
24*36e34afeSAleksandr Iashchenko #endif
25*36e34afeSAleksandr Iashchenko
26d6d1731bSAleksandr Iashchenko #ifndef __ASSEMBLER__
27d6d1731bSAleksandr Iashchenko #include <compiler.h>
28d6d1731bSAleksandr Iashchenko #include <string.h>
29d6d1731bSAleksandr Iashchenko #include <types_ext.h>
30d6d1731bSAleksandr Iashchenko
3160aa5df7SAleksandr Iashchenko #define ASAN_VA_REGS_MAX 32
3260aa5df7SAleksandr Iashchenko
33b8a0c52cSAleksandr Iashchenko enum asan_va_reg_type {
34b8a0c52cSAleksandr Iashchenko ASAN_REG_NO_TYPE,
35b8a0c52cSAleksandr Iashchenko ASAN_REG_STACK,
36b8a0c52cSAleksandr Iashchenko ASAN_REG_MEM_POOL,
37b8a0c52cSAleksandr Iashchenko ASAN_REG_ELF
38b8a0c52cSAleksandr Iashchenko };
39b8a0c52cSAleksandr Iashchenko
4060aa5df7SAleksandr Iashchenko /* Represents memory mapped region */
4160aa5df7SAleksandr Iashchenko struct asan_va_reg {
4260aa5df7SAleksandr Iashchenko vaddr_t lo;
4360aa5df7SAleksandr Iashchenko vaddr_t hi;
4460aa5df7SAleksandr Iashchenko };
4560aa5df7SAleksandr Iashchenko
4660aa5df7SAleksandr Iashchenko /* Global structure with ASan metadata */
4760aa5df7SAleksandr Iashchenko struct asan_global_info {
4860aa5df7SAleksandr Iashchenko /* Virtual memory regions allowed for ASan checks */
4960aa5df7SAleksandr Iashchenko size_t regs_count;
5060aa5df7SAleksandr Iashchenko struct asan_va_reg regs[ASAN_VA_REGS_MAX];
51b8a0c52cSAleksandr Iashchenko enum asan_va_reg_type type[ASAN_VA_REGS_MAX];
524cafd8a3SAleksandr Iashchenko /* Shadow memory regions */
534cafd8a3SAleksandr Iashchenko size_t s_regs_count;
544cafd8a3SAleksandr Iashchenko struct asan_va_reg s_regs[ASAN_VA_REGS_MAX];
5560aa5df7SAleksandr Iashchenko };
5660aa5df7SAleksandr Iashchenko
574cafd8a3SAleksandr Iashchenko #ifdef __KERNEL__
5860aa5df7SAleksandr Iashchenko #define GET_ASAN_INFO() (&__asan_global_info)
594cafd8a3SAleksandr Iashchenko #else
604cafd8a3SAleksandr Iashchenko #define GET_ASAN_INFO() ((struct asan_global_info *) \
614cafd8a3SAleksandr Iashchenko (CFG_USER_ASAN_SHADOW_OFFSET - SMALL_PAGE_SIZE))
624cafd8a3SAleksandr Iashchenko #endif
6360aa5df7SAleksandr Iashchenko
644cafd8a3SAleksandr Iashchenko #if ASAN_IS_ENABLED
654cafd8a3SAleksandr Iashchenko /* ASAN enabled */
66d6d1731bSAleksandr Iashchenko typedef void (*asan_panic_cb_t)(void);
67d6d1731bSAleksandr Iashchenko
68b8a0c52cSAleksandr Iashchenko void asan_add_shadowed(const void *va_begin, const void *va_end,
69b8a0c52cSAleksandr Iashchenko enum asan_va_reg_type type);
70d6d1731bSAleksandr Iashchenko void asan_start(void);
71d6d1731bSAleksandr Iashchenko void asan_panic(void);
72d6d1731bSAleksandr Iashchenko void asan_set_panic_cb(asan_panic_cb_t panic_cb);
73d6d1731bSAleksandr Iashchenko
74d6d1731bSAleksandr Iashchenko void asan_tag_no_access(const void *begin, const void *end);
75d6d1731bSAleksandr Iashchenko void asan_tag_access(const void *begin, const void *end);
76d6d1731bSAleksandr Iashchenko void asan_tag_heap_free(const void *begin, const void *end);
77d6d1731bSAleksandr Iashchenko void *asan_memset_unchecked(void *s, int c, size_t n);
78d6d1731bSAleksandr Iashchenko void *asan_memcpy_unchecked(void *__restrict s1, const void *__restrict s2,
79d6d1731bSAleksandr Iashchenko size_t n);
80b8a0c52cSAleksandr Iashchenko int asan_user_map_shadow(void *lo, void *hi, enum asan_va_reg_type type);
81d6d1731bSAleksandr Iashchenko #else
asan_tag_no_access(const void * begin __unused,const void * end __unused)82d6d1731bSAleksandr Iashchenko static inline void asan_tag_no_access(const void *begin __unused,
83d6d1731bSAleksandr Iashchenko const void *end __unused)
84d6d1731bSAleksandr Iashchenko {
85d6d1731bSAleksandr Iashchenko }
asan_tag_access(const void * begin __unused,const void * end __unused)86d6d1731bSAleksandr Iashchenko static inline void asan_tag_access(const void *begin __unused,
87d6d1731bSAleksandr Iashchenko const void *end __unused)
88d6d1731bSAleksandr Iashchenko {
89d6d1731bSAleksandr Iashchenko }
asan_tag_heap_free(const void * begin __unused,const void * end __unused)90d6d1731bSAleksandr Iashchenko static inline void asan_tag_heap_free(const void *begin __unused,
91d6d1731bSAleksandr Iashchenko const void *end __unused)
92d6d1731bSAleksandr Iashchenko {
93d6d1731bSAleksandr Iashchenko }
94d6d1731bSAleksandr Iashchenko
asan_memset_unchecked(void * s,int c,size_t n)95d6d1731bSAleksandr Iashchenko static inline void *asan_memset_unchecked(void *s, int c, size_t n)
96d6d1731bSAleksandr Iashchenko {
97d6d1731bSAleksandr Iashchenko return memset(s, c, n);
98d6d1731bSAleksandr Iashchenko }
99d6d1731bSAleksandr Iashchenko
asan_memcpy_unchecked(void * __restrict s1,const void * __restrict s2,size_t n)100d6d1731bSAleksandr Iashchenko static inline void *asan_memcpy_unchecked(void *__restrict s1,
101d6d1731bSAleksandr Iashchenko const void *__restrict s2, size_t n)
102d6d1731bSAleksandr Iashchenko {
103d6d1731bSAleksandr Iashchenko return memcpy(s1, s2, n);
104d6d1731bSAleksandr Iashchenko }
105d6d1731bSAleksandr Iashchenko
asan_start(void)1064cafd8a3SAleksandr Iashchenko static inline void asan_start(void)
1074cafd8a3SAleksandr Iashchenko {
1084cafd8a3SAleksandr Iashchenko }
1094cafd8a3SAleksandr Iashchenko
asan_user_map_shadow(void * lo __unused,void * hi __unused,enum asan_va_reg_type type __unused)110b8a0c52cSAleksandr Iashchenko static inline int asan_user_map_shadow(void *lo __unused, void *hi __unused,
111b8a0c52cSAleksandr Iashchenko enum asan_va_reg_type type __unused)
1124cafd8a3SAleksandr Iashchenko {
1134cafd8a3SAleksandr Iashchenko return 0;
1144cafd8a3SAleksandr Iashchenko }
1154cafd8a3SAleksandr Iashchenko #endif /* ASAN_IS_ENABLED */
116d6d1731bSAleksandr Iashchenko
117d6d1731bSAleksandr Iashchenko #endif /*__ASSEMBLER__*/
118d6d1731bSAleksandr Iashchenko #endif /*__ASAN_H*/
119