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 2460aa5df7SAleksandr Iashchenko /* Represents memory mapped region */ 2560aa5df7SAleksandr Iashchenko struct asan_va_reg { 2660aa5df7SAleksandr Iashchenko vaddr_t lo; 2760aa5df7SAleksandr Iashchenko vaddr_t hi; 2860aa5df7SAleksandr Iashchenko }; 2960aa5df7SAleksandr Iashchenko 3060aa5df7SAleksandr Iashchenko /* Global structure with ASan metadata */ 3160aa5df7SAleksandr Iashchenko struct asan_global_info { 3260aa5df7SAleksandr Iashchenko /* Virtual memory regions allowed for ASan checks */ 3360aa5df7SAleksandr Iashchenko size_t regs_count; 3460aa5df7SAleksandr Iashchenko struct asan_va_reg regs[ASAN_VA_REGS_MAX]; 35*4cafd8a3SAleksandr Iashchenko /* Shadow memory regions */ 36*4cafd8a3SAleksandr Iashchenko size_t s_regs_count; 37*4cafd8a3SAleksandr Iashchenko struct asan_va_reg s_regs[ASAN_VA_REGS_MAX]; 3860aa5df7SAleksandr Iashchenko }; 3960aa5df7SAleksandr Iashchenko 40*4cafd8a3SAleksandr Iashchenko #ifdef __KERNEL__ 4160aa5df7SAleksandr Iashchenko #define GET_ASAN_INFO() (&__asan_global_info) 42*4cafd8a3SAleksandr Iashchenko #else 43*4cafd8a3SAleksandr Iashchenko #define GET_ASAN_INFO() ((struct asan_global_info *) \ 44*4cafd8a3SAleksandr Iashchenko (CFG_USER_ASAN_SHADOW_OFFSET - SMALL_PAGE_SIZE)) 45*4cafd8a3SAleksandr Iashchenko #endif 4660aa5df7SAleksandr Iashchenko 47*4cafd8a3SAleksandr Iashchenko #if ((defined(__KERNEL__) || defined(__LDELF__)) && \ 48*4cafd8a3SAleksandr Iashchenko defined(CFG_CORE_SANITIZE_KADDRESS)) 49*4cafd8a3SAleksandr Iashchenko #define ASAN_IS_ENABLED 1 50*4cafd8a3SAleksandr Iashchenko #else 51*4cafd8a3SAleksandr Iashchenko #define ASAN_IS_ENABLED 0 52*4cafd8a3SAleksandr Iashchenko #endif 53*4cafd8a3SAleksandr Iashchenko 54*4cafd8a3SAleksandr Iashchenko #if ASAN_IS_ENABLED 55*4cafd8a3SAleksandr Iashchenko /* ASAN enabled */ 56d6d1731bSAleksandr Iashchenko typedef void (*asan_panic_cb_t)(void); 57d6d1731bSAleksandr Iashchenko 5860aa5df7SAleksandr Iashchenko void asan_add_shadowed(const void *va_begin, const void *va_end); 59d6d1731bSAleksandr Iashchenko void asan_start(void); 60d6d1731bSAleksandr Iashchenko void asan_panic(void); 61d6d1731bSAleksandr Iashchenko void asan_set_panic_cb(asan_panic_cb_t panic_cb); 62d6d1731bSAleksandr Iashchenko 63d6d1731bSAleksandr Iashchenko void asan_tag_no_access(const void *begin, const void *end); 64d6d1731bSAleksandr Iashchenko void asan_tag_access(const void *begin, const void *end); 65d6d1731bSAleksandr Iashchenko void asan_tag_heap_free(const void *begin, const void *end); 66d6d1731bSAleksandr Iashchenko void *asan_memset_unchecked(void *s, int c, size_t n); 67d6d1731bSAleksandr Iashchenko void *asan_memcpy_unchecked(void *__restrict s1, const void *__restrict s2, 68d6d1731bSAleksandr Iashchenko size_t n); 69*4cafd8a3SAleksandr Iashchenko int asan_user_map_shadow(void *lo, void *hi); 70d6d1731bSAleksandr Iashchenko #else 71d6d1731bSAleksandr Iashchenko static inline void asan_tag_no_access(const void *begin __unused, 72d6d1731bSAleksandr Iashchenko const void *end __unused) 73d6d1731bSAleksandr Iashchenko { 74d6d1731bSAleksandr Iashchenko } 75d6d1731bSAleksandr Iashchenko static inline void asan_tag_access(const void *begin __unused, 76d6d1731bSAleksandr Iashchenko const void *end __unused) 77d6d1731bSAleksandr Iashchenko { 78d6d1731bSAleksandr Iashchenko } 79d6d1731bSAleksandr Iashchenko static inline void asan_tag_heap_free(const void *begin __unused, 80d6d1731bSAleksandr Iashchenko const void *end __unused) 81d6d1731bSAleksandr Iashchenko { 82d6d1731bSAleksandr Iashchenko } 83d6d1731bSAleksandr Iashchenko 84d6d1731bSAleksandr Iashchenko static inline void *asan_memset_unchecked(void *s, int c, size_t n) 85d6d1731bSAleksandr Iashchenko { 86d6d1731bSAleksandr Iashchenko return memset(s, c, n); 87d6d1731bSAleksandr Iashchenko } 88d6d1731bSAleksandr Iashchenko 89d6d1731bSAleksandr Iashchenko static inline void *asan_memcpy_unchecked(void *__restrict s1, 90d6d1731bSAleksandr Iashchenko const void *__restrict s2, size_t n) 91d6d1731bSAleksandr Iashchenko { 92d6d1731bSAleksandr Iashchenko return memcpy(s1, s2, n); 93d6d1731bSAleksandr Iashchenko } 94d6d1731bSAleksandr Iashchenko 95*4cafd8a3SAleksandr Iashchenko static inline void asan_start(void) 96*4cafd8a3SAleksandr Iashchenko { 97*4cafd8a3SAleksandr Iashchenko } 98*4cafd8a3SAleksandr Iashchenko 99*4cafd8a3SAleksandr Iashchenko static inline int asan_user_map_shadow(void *lo __unused, void *hi __unused) 100*4cafd8a3SAleksandr Iashchenko { 101*4cafd8a3SAleksandr Iashchenko return 0; 102*4cafd8a3SAleksandr Iashchenko } 103*4cafd8a3SAleksandr Iashchenko #endif /* ASAN_IS_ENABLED */ 104d6d1731bSAleksandr Iashchenko 105d6d1731bSAleksandr Iashchenko #endif /*__ASSEMBLER__*/ 106d6d1731bSAleksandr Iashchenko #endif /*__ASAN_H*/ 107