1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __MM_KASAN_KASAN_H 3 #define __MM_KASAN_KASAN_H 4 5 #include <linux/kasan.h> 6 #include <linux/stackdepot.h> 7 8 #define KASAN_SHADOW_SCALE_SIZE (1UL << KASAN_SHADOW_SCALE_SHIFT) 9 #define KASAN_SHADOW_MASK (KASAN_SHADOW_SCALE_SIZE - 1) 10 11 #define KASAN_TAG_KERNEL 0xFF /* native kernel pointers tag */ 12 #define KASAN_TAG_INVALID 0xFE /* inaccessible memory tag */ 13 #define KASAN_TAG_MAX 0xFD /* maximum value for random tags */ 14 15 #ifdef CONFIG_KASAN_GENERIC 16 #define KASAN_FREE_PAGE 0xFF /* page was freed */ 17 #define KASAN_PAGE_REDZONE 0xFE /* redzone for kmalloc_large allocations */ 18 #define KASAN_KMALLOC_REDZONE 0xFC /* redzone inside slub object */ 19 #define KASAN_KMALLOC_FREE 0xFB /* object was freed (kmem_cache_free/kfree) */ 20 #else 21 #define KASAN_FREE_PAGE KASAN_TAG_INVALID 22 #define KASAN_PAGE_REDZONE KASAN_TAG_INVALID 23 #define KASAN_KMALLOC_REDZONE KASAN_TAG_INVALID 24 #define KASAN_KMALLOC_FREE KASAN_TAG_INVALID 25 #endif 26 27 #define KASAN_GLOBAL_REDZONE 0xFA /* redzone for global variable */ 28 29 /* 30 * Stack redzone shadow values 31 * (Those are compiler's ABI, don't change them) 32 */ 33 #define KASAN_STACK_LEFT 0xF1 34 #define KASAN_STACK_MID 0xF2 35 #define KASAN_STACK_RIGHT 0xF3 36 #define KASAN_STACK_PARTIAL 0xF4 37 38 /* 39 * alloca redzone shadow values 40 */ 41 #define KASAN_ALLOCA_LEFT 0xCA 42 #define KASAN_ALLOCA_RIGHT 0xCB 43 44 #define KASAN_ALLOCA_REDZONE_SIZE 32 45 46 /* 47 * Stack frame marker (compiler ABI). 48 */ 49 #define KASAN_CURRENT_STACK_FRAME_MAGIC 0x41B58AB3 50 51 /* Don't break randconfig/all*config builds */ 52 #ifndef KASAN_ABI_VERSION 53 #define KASAN_ABI_VERSION 1 54 #endif 55 56 struct kasan_access_info { 57 const void *access_addr; 58 const void *first_bad_addr; 59 size_t access_size; 60 bool is_write; 61 unsigned long ip; 62 }; 63 64 /* The layout of struct dictated by compiler */ 65 struct kasan_source_location { 66 const char *filename; 67 int line_no; 68 int column_no; 69 }; 70 71 /* The layout of struct dictated by compiler */ 72 struct kasan_global { 73 const void *beg; /* Address of the beginning of the global variable. */ 74 size_t size; /* Size of the global variable. */ 75 size_t size_with_redzone; /* Size of the variable + size of the red zone. 32 bytes aligned */ 76 const void *name; 77 const void *module_name; /* Name of the module where the global variable is declared. */ 78 unsigned long has_dynamic_init; /* This needed for C++ */ 79 #if KASAN_ABI_VERSION >= 4 80 struct kasan_source_location *location; 81 #endif 82 #if KASAN_ABI_VERSION >= 5 83 char *odr_indicator; 84 #endif 85 }; 86 87 /** 88 * Structures to keep alloc and free tracks * 89 */ 90 91 #define KASAN_STACK_DEPTH 64 92 93 struct kasan_track { 94 u32 pid; 95 depot_stack_handle_t stack; 96 }; 97 98 #ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY 99 #define KASAN_NR_FREE_STACKS 5 100 #else 101 #define KASAN_NR_FREE_STACKS 1 102 #endif 103 104 struct kasan_alloc_meta { 105 struct kasan_track alloc_track; 106 struct kasan_track free_track[KASAN_NR_FREE_STACKS]; 107 #ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY 108 u8 free_pointer_tag[KASAN_NR_FREE_STACKS]; 109 u8 free_track_idx; 110 #endif 111 }; 112 113 struct qlist_node { 114 struct qlist_node *next; 115 }; 116 struct kasan_free_meta { 117 /* This field is used while the object is in the quarantine. 118 * Otherwise it might be used for the allocator freelist. 119 */ 120 struct qlist_node quarantine_link; 121 }; 122 123 struct kasan_alloc_meta *get_alloc_info(struct kmem_cache *cache, 124 const void *object); 125 struct kasan_free_meta *get_free_info(struct kmem_cache *cache, 126 const void *object); 127 128 static inline const void *kasan_shadow_to_mem(const void *shadow_addr) 129 { 130 return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET) 131 << KASAN_SHADOW_SCALE_SHIFT); 132 } 133 134 static inline bool addr_has_shadow(const void *addr) 135 { 136 return (addr >= kasan_shadow_to_mem((void *)KASAN_SHADOW_START)); 137 } 138 139 void kasan_poison_shadow(const void *address, size_t size, u8 value); 140 141 /** 142 * check_memory_region - Check memory region, and report if invalid access. 143 * @addr: the accessed address 144 * @size: the accessed size 145 * @write: true if access is a write access 146 * @ret_ip: return address 147 * @return: true if access was valid, false if invalid 148 */ 149 bool check_memory_region(unsigned long addr, size_t size, bool write, 150 unsigned long ret_ip); 151 152 void *find_first_bad_addr(void *addr, size_t size); 153 const char *get_bug_type(struct kasan_access_info *info); 154 155 void kasan_report(unsigned long addr, size_t size, 156 bool is_write, unsigned long ip); 157 void kasan_report_invalid_free(void *object, unsigned long ip); 158 159 struct page *kasan_addr_to_page(const void *addr); 160 161 #if defined(CONFIG_KASAN_GENERIC) && \ 162 (defined(CONFIG_SLAB) || defined(CONFIG_SLUB)) 163 void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache); 164 void quarantine_reduce(void); 165 void quarantine_remove_cache(struct kmem_cache *cache); 166 #else 167 static inline void quarantine_put(struct kasan_free_meta *info, 168 struct kmem_cache *cache) { } 169 static inline void quarantine_reduce(void) { } 170 static inline void quarantine_remove_cache(struct kmem_cache *cache) { } 171 #endif 172 173 #ifdef CONFIG_KASAN_SW_TAGS 174 175 void print_tags(u8 addr_tag, const void *addr); 176 177 u8 random_tag(void); 178 179 #else 180 181 static inline void print_tags(u8 addr_tag, const void *addr) { } 182 183 static inline u8 random_tag(void) 184 { 185 return 0; 186 } 187 188 #endif 189 190 #ifndef arch_kasan_set_tag 191 static inline const void *arch_kasan_set_tag(const void *addr, u8 tag) 192 { 193 return addr; 194 } 195 #endif 196 #ifndef arch_kasan_reset_tag 197 #define arch_kasan_reset_tag(addr) ((void *)(addr)) 198 #endif 199 #ifndef arch_kasan_get_tag 200 #define arch_kasan_get_tag(addr) 0 201 #endif 202 203 #define set_tag(addr, tag) ((void *)arch_kasan_set_tag((addr), (tag))) 204 #define reset_tag(addr) ((void *)arch_kasan_reset_tag(addr)) 205 #define get_tag(addr) arch_kasan_get_tag(addr) 206 207 /* 208 * Exported functions for interfaces called from assembly or from generated 209 * code. Declarations here to avoid warning about missing declarations. 210 */ 211 asmlinkage void kasan_unpoison_task_stack_below(const void *watermark); 212 void __asan_register_globals(struct kasan_global *globals, size_t size); 213 void __asan_unregister_globals(struct kasan_global *globals, size_t size); 214 void __asan_loadN(unsigned long addr, size_t size); 215 void __asan_storeN(unsigned long addr, size_t size); 216 void __asan_handle_no_return(void); 217 void __asan_alloca_poison(unsigned long addr, size_t size); 218 void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom); 219 220 void __asan_load1(unsigned long addr); 221 void __asan_store1(unsigned long addr); 222 void __asan_load2(unsigned long addr); 223 void __asan_store2(unsigned long addr); 224 void __asan_load4(unsigned long addr); 225 void __asan_store4(unsigned long addr); 226 void __asan_load8(unsigned long addr); 227 void __asan_store8(unsigned long addr); 228 void __asan_load16(unsigned long addr); 229 void __asan_store16(unsigned long addr); 230 231 void __asan_load1_noabort(unsigned long addr); 232 void __asan_store1_noabort(unsigned long addr); 233 void __asan_load2_noabort(unsigned long addr); 234 void __asan_store2_noabort(unsigned long addr); 235 void __asan_load4_noabort(unsigned long addr); 236 void __asan_store4_noabort(unsigned long addr); 237 void __asan_load8_noabort(unsigned long addr); 238 void __asan_store8_noabort(unsigned long addr); 239 void __asan_load16_noabort(unsigned long addr); 240 void __asan_store16_noabort(unsigned long addr); 241 242 void __asan_set_shadow_00(const void *addr, size_t size); 243 void __asan_set_shadow_f1(const void *addr, size_t size); 244 void __asan_set_shadow_f2(const void *addr, size_t size); 245 void __asan_set_shadow_f3(const void *addr, size_t size); 246 void __asan_set_shadow_f5(const void *addr, size_t size); 247 void __asan_set_shadow_f8(const void *addr, size_t size); 248 249 #endif 250