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 17d6d1731bSAleksandr Iashchenko #ifndef __ASSEMBLER__ 18d6d1731bSAleksandr Iashchenko #include <compiler.h> 19d6d1731bSAleksandr Iashchenko #include <string.h> 20d6d1731bSAleksandr Iashchenko #include <types_ext.h> 21d6d1731bSAleksandr Iashchenko 2260aa5df7SAleksandr Iashchenko #define ASAN_VA_REGS_MAX 32 2360aa5df7SAleksandr Iashchenko 24*b8a0c52cSAleksandr Iashchenko enum asan_va_reg_type { 25*b8a0c52cSAleksandr Iashchenko ASAN_REG_NO_TYPE, 26*b8a0c52cSAleksandr Iashchenko ASAN_REG_STACK, 27*b8a0c52cSAleksandr Iashchenko ASAN_REG_MEM_POOL, 28*b8a0c52cSAleksandr Iashchenko ASAN_REG_ELF 29*b8a0c52cSAleksandr Iashchenko }; 30*b8a0c52cSAleksandr Iashchenko 3160aa5df7SAleksandr Iashchenko /* Represents memory mapped region */ 3260aa5df7SAleksandr Iashchenko struct asan_va_reg { 3360aa5df7SAleksandr Iashchenko vaddr_t lo; 3460aa5df7SAleksandr Iashchenko vaddr_t hi; 3560aa5df7SAleksandr Iashchenko }; 3660aa5df7SAleksandr Iashchenko 3760aa5df7SAleksandr Iashchenko /* Global structure with ASan metadata */ 3860aa5df7SAleksandr Iashchenko struct asan_global_info { 3960aa5df7SAleksandr Iashchenko /* Virtual memory regions allowed for ASan checks */ 4060aa5df7SAleksandr Iashchenko size_t regs_count; 4160aa5df7SAleksandr Iashchenko struct asan_va_reg regs[ASAN_VA_REGS_MAX]; 42*b8a0c52cSAleksandr Iashchenko enum asan_va_reg_type type[ASAN_VA_REGS_MAX]; 434cafd8a3SAleksandr Iashchenko /* Shadow memory regions */ 444cafd8a3SAleksandr Iashchenko size_t s_regs_count; 454cafd8a3SAleksandr Iashchenko struct asan_va_reg s_regs[ASAN_VA_REGS_MAX]; 4660aa5df7SAleksandr Iashchenko }; 4760aa5df7SAleksandr Iashchenko 484cafd8a3SAleksandr Iashchenko #ifdef __KERNEL__ 4960aa5df7SAleksandr Iashchenko #define GET_ASAN_INFO() (&__asan_global_info) 504cafd8a3SAleksandr Iashchenko #else 514cafd8a3SAleksandr Iashchenko #define GET_ASAN_INFO() ((struct asan_global_info *) \ 524cafd8a3SAleksandr Iashchenko (CFG_USER_ASAN_SHADOW_OFFSET - SMALL_PAGE_SIZE)) 534cafd8a3SAleksandr Iashchenko #endif 5460aa5df7SAleksandr Iashchenko 559f2dc7a1SAleksandr Iashchenko #if ((!defined(__KERNEL__) && !defined(__LDELF__)) && \ 569f2dc7a1SAleksandr Iashchenko defined(CFG_TA_SANITIZE_KADDRESS)) || \ 579f2dc7a1SAleksandr Iashchenko ((defined(__KERNEL__) || defined(__LDELF__)) && \ 584cafd8a3SAleksandr Iashchenko defined(CFG_CORE_SANITIZE_KADDRESS)) 594cafd8a3SAleksandr Iashchenko #define ASAN_IS_ENABLED 1 604cafd8a3SAleksandr Iashchenko #else 614cafd8a3SAleksandr Iashchenko #define ASAN_IS_ENABLED 0 624cafd8a3SAleksandr Iashchenko #endif 634cafd8a3SAleksandr Iashchenko 644cafd8a3SAleksandr Iashchenko #if ASAN_IS_ENABLED 654cafd8a3SAleksandr Iashchenko /* ASAN enabled */ 66d6d1731bSAleksandr Iashchenko typedef void (*asan_panic_cb_t)(void); 67d6d1731bSAleksandr Iashchenko 68*b8a0c52cSAleksandr Iashchenko void asan_add_shadowed(const void *va_begin, const void *va_end, 69*b8a0c52cSAleksandr 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); 80*b8a0c52cSAleksandr Iashchenko int asan_user_map_shadow(void *lo, void *hi, enum asan_va_reg_type type); 81d6d1731bSAleksandr Iashchenko #else 82d6d1731bSAleksandr Iashchenko static inline void asan_tag_no_access(const void *begin __unused, 83d6d1731bSAleksandr Iashchenko const void *end __unused) 84d6d1731bSAleksandr Iashchenko { 85d6d1731bSAleksandr Iashchenko } 86d6d1731bSAleksandr Iashchenko static inline void asan_tag_access(const void *begin __unused, 87d6d1731bSAleksandr Iashchenko const void *end __unused) 88d6d1731bSAleksandr Iashchenko { 89d6d1731bSAleksandr Iashchenko } 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 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 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 1064cafd8a3SAleksandr Iashchenko static inline void asan_start(void) 1074cafd8a3SAleksandr Iashchenko { 1084cafd8a3SAleksandr Iashchenko } 1094cafd8a3SAleksandr Iashchenko 110*b8a0c52cSAleksandr Iashchenko static inline int asan_user_map_shadow(void *lo __unused, void *hi __unused, 111*b8a0c52cSAleksandr 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