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