1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 20b24beccSAndrey Ryabinin #ifndef _LINUX_KASAN_H 30b24beccSAndrey Ryabinin #define _LINUX_KASAN_H 40b24beccSAndrey Ryabinin 57a3b8353SPeter Collingbourne #include <linux/bug.h> 6f9b5e46fSPeter Collingbourne #include <linux/kasan-enabled.h> 72db710ccSMarco Elver #include <linux/kernel.h> 834303244SAndrey Konovalov #include <linux/static_key.h> 90b24beccSAndrey Ryabinin #include <linux/types.h> 100b24beccSAndrey Ryabinin 110b24beccSAndrey Ryabinin struct kmem_cache; 120b24beccSAndrey Ryabinin struct page; 136e48a966SMatthew Wilcox (Oracle) struct slab; 14a5af5aa8SAndrey Ryabinin struct vm_struct; 155be9b730SMasami Hiramatsu struct task_struct; 160b24beccSAndrey Ryabinin 170b24beccSAndrey Ryabinin #ifdef CONFIG_KASAN 180b24beccSAndrey Ryabinin 19d5750edfSAndrey Konovalov #include <linux/linkage.h> 2065fddcfcSMike Rapoport #include <asm/kasan.h> 210b24beccSAndrey Ryabinin 2283c4e7a0SPatricia Alfonso /* kasan_data struct is used in KUnit tests for KASAN expected failures */ 2383c4e7a0SPatricia Alfonso struct kunit_kasan_expectation { 2483c4e7a0SPatricia Alfonso bool report_found; 2583c4e7a0SPatricia Alfonso }; 2683c4e7a0SPatricia Alfonso 27d5750edfSAndrey Konovalov #endif 28d5750edfSAndrey Konovalov 29*23689e91SAndrey Konovalov typedef unsigned int __bitwise kasan_vmalloc_flags_t; 30*23689e91SAndrey Konovalov 31*23689e91SAndrey Konovalov #define KASAN_VMALLOC_NONE 0x00u 32*23689e91SAndrey Konovalov #define KASAN_VMALLOC_INIT 0x01u 33*23689e91SAndrey Konovalov #define KASAN_VMALLOC_VM_ALLOC 0x02u 34*23689e91SAndrey Konovalov 35d5750edfSAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) 36d5750edfSAndrey Konovalov 37d5750edfSAndrey Konovalov #include <linux/pgtable.h> 38d5750edfSAndrey Konovalov 39d5750edfSAndrey Konovalov /* Software KASAN implementations use shadow memory. */ 40d5750edfSAndrey Konovalov 41d5750edfSAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS 42a064cb00SAndrey Konovalov /* This matches KASAN_TAG_INVALID. */ 43a064cb00SAndrey Konovalov #define KASAN_SHADOW_INIT 0xFE 44d5750edfSAndrey Konovalov #else 45d5750edfSAndrey Konovalov #define KASAN_SHADOW_INIT 0 46d5750edfSAndrey Konovalov #endif 47d5750edfSAndrey Konovalov 4829970dc2SHailong Liu #ifndef PTE_HWTABLE_PTRS 4929970dc2SHailong Liu #define PTE_HWTABLE_PTRS 0 5029970dc2SHailong Liu #endif 5129970dc2SHailong Liu 529577dd74SAndrey Konovalov extern unsigned char kasan_early_shadow_page[PAGE_SIZE]; 53cb32c9c5SDaniel Axtens extern pte_t kasan_early_shadow_pte[MAX_PTRS_PER_PTE + PTE_HWTABLE_PTRS]; 54cb32c9c5SDaniel Axtens extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD]; 55cb32c9c5SDaniel Axtens extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD]; 569577dd74SAndrey Konovalov extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D]; 5769786cdbSAndrey Ryabinin 589577dd74SAndrey Konovalov int kasan_populate_early_shadow(const void *shadow_start, 5969786cdbSAndrey Ryabinin const void *shadow_end); 6069786cdbSAndrey Ryabinin 610b24beccSAndrey Ryabinin static inline void *kasan_mem_to_shadow(const void *addr) 620b24beccSAndrey Ryabinin { 630b24beccSAndrey Ryabinin return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) 640b24beccSAndrey Ryabinin + KASAN_SHADOW_OFFSET; 650b24beccSAndrey Ryabinin } 660b24beccSAndrey Ryabinin 67d5750edfSAndrey Konovalov int kasan_add_zero_shadow(void *start, unsigned long size); 68d5750edfSAndrey Konovalov void kasan_remove_zero_shadow(void *start, unsigned long size); 69d5750edfSAndrey Konovalov 70d73b4936SAndrey Konovalov /* Enable reporting bugs after kasan_disable_current() */ 71d73b4936SAndrey Konovalov extern void kasan_enable_current(void); 72d73b4936SAndrey Konovalov 73d73b4936SAndrey Konovalov /* Disable reporting bugs for current task */ 74d73b4936SAndrey Konovalov extern void kasan_disable_current(void); 75d73b4936SAndrey Konovalov 76d5750edfSAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 77d5750edfSAndrey Konovalov 78d5750edfSAndrey Konovalov static inline int kasan_add_zero_shadow(void *start, unsigned long size) 79d5750edfSAndrey Konovalov { 80d5750edfSAndrey Konovalov return 0; 81d5750edfSAndrey Konovalov } 82d5750edfSAndrey Konovalov static inline void kasan_remove_zero_shadow(void *start, 83d5750edfSAndrey Konovalov unsigned long size) 84d5750edfSAndrey Konovalov {} 85d5750edfSAndrey Konovalov 86d73b4936SAndrey Konovalov static inline void kasan_enable_current(void) {} 87d73b4936SAndrey Konovalov static inline void kasan_disable_current(void) {} 88d73b4936SAndrey Konovalov 89d5750edfSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 90d5750edfSAndrey Konovalov 9134303244SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 92e86f8b09SAndrey Konovalov 93e86f8b09SAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */ 94e86f8b09SAndrey Konovalov 95e86f8b09SAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */ 96e86f8b09SAndrey Konovalov 97e5af50a5SPeter Collingbourne static inline bool kasan_has_integrated_init(void) 98e5af50a5SPeter Collingbourne { 99e5af50a5SPeter Collingbourne return kasan_hw_tags_enabled(); 100e5af50a5SPeter Collingbourne } 101e5af50a5SPeter Collingbourne 1027a3b8353SPeter Collingbourne #ifdef CONFIG_KASAN 1037a3b8353SPeter Collingbourne 1047a3b8353SPeter Collingbourne struct kasan_cache { 1057a3b8353SPeter Collingbourne int alloc_meta_offset; 1067a3b8353SPeter Collingbourne int free_meta_offset; 1077a3b8353SPeter Collingbourne bool is_kmalloc; 1087a3b8353SPeter Collingbourne }; 1097a3b8353SPeter Collingbourne 110e86f8b09SAndrey Konovalov slab_flags_t __kasan_never_merge(void); 111e86f8b09SAndrey Konovalov static __always_inline slab_flags_t kasan_never_merge(void) 112e86f8b09SAndrey Konovalov { 113e86f8b09SAndrey Konovalov if (kasan_enabled()) 114e86f8b09SAndrey Konovalov return __kasan_never_merge(); 115e86f8b09SAndrey Konovalov return 0; 116e86f8b09SAndrey Konovalov } 11734303244SAndrey Konovalov 11834303244SAndrey Konovalov void __kasan_unpoison_range(const void *addr, size_t size); 11934303244SAndrey Konovalov static __always_inline void kasan_unpoison_range(const void *addr, size_t size) 12034303244SAndrey Konovalov { 12134303244SAndrey Konovalov if (kasan_enabled()) 12234303244SAndrey Konovalov __kasan_unpoison_range(addr, size); 12334303244SAndrey Konovalov } 12434303244SAndrey Konovalov 1257a3b8353SPeter Collingbourne void __kasan_poison_pages(struct page *page, unsigned int order, bool init); 1267a3b8353SPeter Collingbourne static __always_inline void kasan_poison_pages(struct page *page, 1271bb5eab3SAndrey Konovalov unsigned int order, bool init) 12834303244SAndrey Konovalov { 12934303244SAndrey Konovalov if (kasan_enabled()) 1307a3b8353SPeter Collingbourne __kasan_poison_pages(page, order, init); 13134303244SAndrey Konovalov } 13234303244SAndrey Konovalov 1337a3b8353SPeter Collingbourne void __kasan_unpoison_pages(struct page *page, unsigned int order, bool init); 1347a3b8353SPeter Collingbourne static __always_inline void kasan_unpoison_pages(struct page *page, 1351bb5eab3SAndrey Konovalov unsigned int order, bool init) 13634303244SAndrey Konovalov { 13734303244SAndrey Konovalov if (kasan_enabled()) 1387a3b8353SPeter Collingbourne __kasan_unpoison_pages(page, order, init); 13934303244SAndrey Konovalov } 14034303244SAndrey Konovalov 14134303244SAndrey Konovalov void __kasan_cache_create(struct kmem_cache *cache, unsigned int *size, 14234303244SAndrey Konovalov slab_flags_t *flags); 14334303244SAndrey Konovalov static __always_inline void kasan_cache_create(struct kmem_cache *cache, 14434303244SAndrey Konovalov unsigned int *size, slab_flags_t *flags) 14534303244SAndrey Konovalov { 14634303244SAndrey Konovalov if (kasan_enabled()) 14734303244SAndrey Konovalov __kasan_cache_create(cache, size, flags); 14834303244SAndrey Konovalov } 14934303244SAndrey Konovalov 15092850134SAndrey Konovalov void __kasan_cache_create_kmalloc(struct kmem_cache *cache); 15192850134SAndrey Konovalov static __always_inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) 15292850134SAndrey Konovalov { 15392850134SAndrey Konovalov if (kasan_enabled()) 15492850134SAndrey Konovalov __kasan_cache_create_kmalloc(cache); 15592850134SAndrey Konovalov } 15692850134SAndrey Konovalov 15734303244SAndrey Konovalov size_t __kasan_metadata_size(struct kmem_cache *cache); 15834303244SAndrey Konovalov static __always_inline size_t kasan_metadata_size(struct kmem_cache *cache) 15934303244SAndrey Konovalov { 16034303244SAndrey Konovalov if (kasan_enabled()) 16134303244SAndrey Konovalov return __kasan_metadata_size(cache); 16234303244SAndrey Konovalov return 0; 16334303244SAndrey Konovalov } 16434303244SAndrey Konovalov 1656e48a966SMatthew Wilcox (Oracle) void __kasan_poison_slab(struct slab *slab); 1666e48a966SMatthew Wilcox (Oracle) static __always_inline void kasan_poison_slab(struct slab *slab) 16734303244SAndrey Konovalov { 16834303244SAndrey Konovalov if (kasan_enabled()) 1696e48a966SMatthew Wilcox (Oracle) __kasan_poison_slab(slab); 17034303244SAndrey Konovalov } 17134303244SAndrey Konovalov 17234303244SAndrey Konovalov void __kasan_unpoison_object_data(struct kmem_cache *cache, void *object); 17334303244SAndrey Konovalov static __always_inline void kasan_unpoison_object_data(struct kmem_cache *cache, 17434303244SAndrey Konovalov void *object) 17534303244SAndrey Konovalov { 17634303244SAndrey Konovalov if (kasan_enabled()) 17734303244SAndrey Konovalov __kasan_unpoison_object_data(cache, object); 17834303244SAndrey Konovalov } 17934303244SAndrey Konovalov 18034303244SAndrey Konovalov void __kasan_poison_object_data(struct kmem_cache *cache, void *object); 18134303244SAndrey Konovalov static __always_inline void kasan_poison_object_data(struct kmem_cache *cache, 18234303244SAndrey Konovalov void *object) 18334303244SAndrey Konovalov { 18434303244SAndrey Konovalov if (kasan_enabled()) 18534303244SAndrey Konovalov __kasan_poison_object_data(cache, object); 18634303244SAndrey Konovalov } 18734303244SAndrey Konovalov 18834303244SAndrey Konovalov void * __must_check __kasan_init_slab_obj(struct kmem_cache *cache, 18934303244SAndrey Konovalov const void *object); 19034303244SAndrey Konovalov static __always_inline void * __must_check kasan_init_slab_obj( 19134303244SAndrey Konovalov struct kmem_cache *cache, const void *object) 19234303244SAndrey Konovalov { 19334303244SAndrey Konovalov if (kasan_enabled()) 19434303244SAndrey Konovalov return __kasan_init_slab_obj(cache, object); 19534303244SAndrey Konovalov return (void *)object; 19634303244SAndrey Konovalov } 19734303244SAndrey Konovalov 198d57a964eSAndrey Konovalov bool __kasan_slab_free(struct kmem_cache *s, void *object, 199d57a964eSAndrey Konovalov unsigned long ip, bool init); 200d57a964eSAndrey Konovalov static __always_inline bool kasan_slab_free(struct kmem_cache *s, 201d57a964eSAndrey Konovalov void *object, bool init) 20234303244SAndrey Konovalov { 20334303244SAndrey Konovalov if (kasan_enabled()) 204d57a964eSAndrey Konovalov return __kasan_slab_free(s, object, _RET_IP_, init); 20534303244SAndrey Konovalov return false; 20634303244SAndrey Konovalov } 20734303244SAndrey Konovalov 208200072ceSAndrey Konovalov void __kasan_kfree_large(void *ptr, unsigned long ip); 209200072ceSAndrey Konovalov static __always_inline void kasan_kfree_large(void *ptr) 210200072ceSAndrey Konovalov { 211200072ceSAndrey Konovalov if (kasan_enabled()) 212200072ceSAndrey Konovalov __kasan_kfree_large(ptr, _RET_IP_); 213200072ceSAndrey Konovalov } 214200072ceSAndrey Konovalov 215eeb3160cSAndrey Konovalov void __kasan_slab_free_mempool(void *ptr, unsigned long ip); 216027b37b5SAndrey Konovalov static __always_inline void kasan_slab_free_mempool(void *ptr) 217eeb3160cSAndrey Konovalov { 218eeb3160cSAndrey Konovalov if (kasan_enabled()) 219027b37b5SAndrey Konovalov __kasan_slab_free_mempool(ptr, _RET_IP_); 220eeb3160cSAndrey Konovalov } 221eeb3160cSAndrey Konovalov 22234303244SAndrey Konovalov void * __must_check __kasan_slab_alloc(struct kmem_cache *s, 223da844b78SAndrey Konovalov void *object, gfp_t flags, bool init); 22434303244SAndrey Konovalov static __always_inline void * __must_check kasan_slab_alloc( 225da844b78SAndrey Konovalov struct kmem_cache *s, void *object, gfp_t flags, bool init) 22634303244SAndrey Konovalov { 22734303244SAndrey Konovalov if (kasan_enabled()) 228da844b78SAndrey Konovalov return __kasan_slab_alloc(s, object, flags, init); 22934303244SAndrey Konovalov return object; 23034303244SAndrey Konovalov } 23134303244SAndrey Konovalov 23234303244SAndrey Konovalov void * __must_check __kasan_kmalloc(struct kmem_cache *s, const void *object, 23334303244SAndrey Konovalov size_t size, gfp_t flags); 23434303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc(struct kmem_cache *s, 23534303244SAndrey Konovalov const void *object, size_t size, gfp_t flags) 23634303244SAndrey Konovalov { 23734303244SAndrey Konovalov if (kasan_enabled()) 23834303244SAndrey Konovalov return __kasan_kmalloc(s, object, size, flags); 23934303244SAndrey Konovalov return (void *)object; 24034303244SAndrey Konovalov } 24134303244SAndrey Konovalov 24234303244SAndrey Konovalov void * __must_check __kasan_kmalloc_large(const void *ptr, 24334303244SAndrey Konovalov size_t size, gfp_t flags); 24434303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc_large(const void *ptr, 24534303244SAndrey Konovalov size_t size, gfp_t flags) 24634303244SAndrey Konovalov { 24734303244SAndrey Konovalov if (kasan_enabled()) 24834303244SAndrey Konovalov return __kasan_kmalloc_large(ptr, size, flags); 24934303244SAndrey Konovalov return (void *)ptr; 25034303244SAndrey Konovalov } 25134303244SAndrey Konovalov 25234303244SAndrey Konovalov void * __must_check __kasan_krealloc(const void *object, 25334303244SAndrey Konovalov size_t new_size, gfp_t flags); 25434303244SAndrey Konovalov static __always_inline void * __must_check kasan_krealloc(const void *object, 25534303244SAndrey Konovalov size_t new_size, gfp_t flags) 25634303244SAndrey Konovalov { 25734303244SAndrey Konovalov if (kasan_enabled()) 25834303244SAndrey Konovalov return __kasan_krealloc(object, new_size, flags); 25934303244SAndrey Konovalov return (void *)object; 26034303244SAndrey Konovalov } 26134303244SAndrey Konovalov 262611806b4SAndrey Konovalov /* 263611806b4SAndrey Konovalov * Unlike kasan_check_read/write(), kasan_check_byte() is performed even for 264611806b4SAndrey Konovalov * the hardware tag-based mode that doesn't rely on compiler instrumentation. 265611806b4SAndrey Konovalov */ 266611806b4SAndrey Konovalov bool __kasan_check_byte(const void *addr, unsigned long ip); 267611806b4SAndrey Konovalov static __always_inline bool kasan_check_byte(const void *addr) 268611806b4SAndrey Konovalov { 269611806b4SAndrey Konovalov if (kasan_enabled()) 270611806b4SAndrey Konovalov return __kasan_check_byte(addr, _RET_IP_); 271611806b4SAndrey Konovalov return true; 272611806b4SAndrey Konovalov } 273611806b4SAndrey Konovalov 274611806b4SAndrey Konovalov 275b0845ce5SMark Rutland bool kasan_save_enable_multi_shot(void); 276b0845ce5SMark Rutland void kasan_restore_multi_shot(bool enabled); 277b0845ce5SMark Rutland 2780b24beccSAndrey Ryabinin #else /* CONFIG_KASAN */ 2790b24beccSAndrey Ryabinin 280e86f8b09SAndrey Konovalov static inline slab_flags_t kasan_never_merge(void) 281e86f8b09SAndrey Konovalov { 282e86f8b09SAndrey Konovalov return 0; 283e86f8b09SAndrey Konovalov } 284cebd0eb2SAndrey Konovalov static inline void kasan_unpoison_range(const void *address, size_t size) {} 2857a3b8353SPeter Collingbourne static inline void kasan_poison_pages(struct page *page, unsigned int order, 2867a3b8353SPeter Collingbourne bool init) {} 2877a3b8353SPeter Collingbourne static inline void kasan_unpoison_pages(struct page *page, unsigned int order, 2887a3b8353SPeter Collingbourne bool init) {} 2897ed2f9e6SAlexander Potapenko static inline void kasan_cache_create(struct kmem_cache *cache, 290be4a7988SAlexey Dobriyan unsigned int *size, 291d50112edSAlexey Dobriyan slab_flags_t *flags) {} 29292850134SAndrey Konovalov static inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) {} 29334303244SAndrey Konovalov static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; } 2946e48a966SMatthew Wilcox (Oracle) static inline void kasan_poison_slab(struct slab *slab) {} 2950316bec2SAndrey Ryabinin static inline void kasan_unpoison_object_data(struct kmem_cache *cache, 2960316bec2SAndrey Ryabinin void *object) {} 2970316bec2SAndrey Ryabinin static inline void kasan_poison_object_data(struct kmem_cache *cache, 2980316bec2SAndrey Ryabinin void *object) {} 2990116523cSAndrey Konovalov static inline void *kasan_init_slab_obj(struct kmem_cache *cache, 3000116523cSAndrey Konovalov const void *object) 3010116523cSAndrey Konovalov { 3020116523cSAndrey Konovalov return (void *)object; 3030116523cSAndrey Konovalov } 304d57a964eSAndrey Konovalov static inline bool kasan_slab_free(struct kmem_cache *s, void *object, bool init) 3050116523cSAndrey Konovalov { 30634303244SAndrey Konovalov return false; 3070116523cSAndrey Konovalov } 308200072ceSAndrey Konovalov static inline void kasan_kfree_large(void *ptr) {} 309027b37b5SAndrey Konovalov static inline void kasan_slab_free_mempool(void *ptr) {} 31034303244SAndrey Konovalov static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object, 311da844b78SAndrey Konovalov gfp_t flags, bool init) 31234303244SAndrey Konovalov { 31334303244SAndrey Konovalov return object; 31434303244SAndrey Konovalov } 3150116523cSAndrey Konovalov static inline void *kasan_kmalloc(struct kmem_cache *s, const void *object, 3160116523cSAndrey Konovalov size_t size, gfp_t flags) 3170116523cSAndrey Konovalov { 3180116523cSAndrey Konovalov return (void *)object; 3190116523cSAndrey Konovalov } 32034303244SAndrey Konovalov static inline void *kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags) 32134303244SAndrey Konovalov { 32234303244SAndrey Konovalov return (void *)ptr; 32334303244SAndrey Konovalov } 3240116523cSAndrey Konovalov static inline void *kasan_krealloc(const void *object, size_t new_size, 3250116523cSAndrey Konovalov gfp_t flags) 3260116523cSAndrey Konovalov { 3270116523cSAndrey Konovalov return (void *)object; 3280116523cSAndrey Konovalov } 329611806b4SAndrey Konovalov static inline bool kasan_check_byte(const void *address) 330611806b4SAndrey Konovalov { 331611806b4SAndrey Konovalov return true; 332611806b4SAndrey Konovalov } 3339b75a867SAndrey Ryabinin 3340b24beccSAndrey Ryabinin #endif /* CONFIG_KASAN */ 3350b24beccSAndrey Ryabinin 33602c58773SWalter Wu #if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK) 337d56a9ef8SAndrey Konovalov void kasan_unpoison_task_stack(struct task_struct *task); 338d56a9ef8SAndrey Konovalov #else 339d56a9ef8SAndrey Konovalov static inline void kasan_unpoison_task_stack(struct task_struct *task) {} 340d56a9ef8SAndrey Konovalov #endif 341d56a9ef8SAndrey Konovalov 3422bd926b4SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC 3432bd926b4SAndrey Konovalov 3442bd926b4SAndrey Konovalov void kasan_cache_shrink(struct kmem_cache *cache); 3452bd926b4SAndrey Konovalov void kasan_cache_shutdown(struct kmem_cache *cache); 34626e760c9SWalter Wu void kasan_record_aux_stack(void *ptr); 3477cb3007cSMarco Elver void kasan_record_aux_stack_noalloc(void *ptr); 3482bd926b4SAndrey Konovalov 3492bd926b4SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC */ 3502bd926b4SAndrey Konovalov 3512bd926b4SAndrey Konovalov static inline void kasan_cache_shrink(struct kmem_cache *cache) {} 3522bd926b4SAndrey Konovalov static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} 35326e760c9SWalter Wu static inline void kasan_record_aux_stack(void *ptr) {} 3547cb3007cSMarco Elver static inline void kasan_record_aux_stack_noalloc(void *ptr) {} 3552bd926b4SAndrey Konovalov 3562bd926b4SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */ 3572bd926b4SAndrey Konovalov 3582e903b91SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) 3593c9e3aa1SAndrey Konovalov 360c0054c56SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 361c0054c56SAndrey Konovalov { 362c0054c56SAndrey Konovalov return (void *)arch_kasan_reset_tag(addr); 363c0054c56SAndrey Konovalov } 3643c9e3aa1SAndrey Konovalov 36549c6631dSVincenzo Frascino /** 36649c6631dSVincenzo Frascino * kasan_report - print a report about a bad memory access detected by KASAN 36749c6631dSVincenzo Frascino * @addr: address of the bad access 36849c6631dSVincenzo Frascino * @size: size of the bad access 36949c6631dSVincenzo Frascino * @is_write: whether the bad access is a write or a read 37049c6631dSVincenzo Frascino * @ip: instruction pointer for the accessibility check or the bad access itself 37149c6631dSVincenzo Frascino */ 3728cceeff4SWalter Wu bool kasan_report(unsigned long addr, size_t size, 37341eea9cdSAndrey Konovalov bool is_write, unsigned long ip); 37441eea9cdSAndrey Konovalov 3752e903b91SAndrey Konovalov #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */ 3763c9e3aa1SAndrey Konovalov 3773c9e3aa1SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 3783c9e3aa1SAndrey Konovalov { 3793c9e3aa1SAndrey Konovalov return (void *)addr; 3803c9e3aa1SAndrey Konovalov } 3813c9e3aa1SAndrey Konovalov 3822e903b91SAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS*/ 3832e903b91SAndrey Konovalov 3848f7b5054SVincenzo Frascino #ifdef CONFIG_KASAN_HW_TAGS 3858f7b5054SVincenzo Frascino 3868f7b5054SVincenzo Frascino void kasan_report_async(void); 3878f7b5054SVincenzo Frascino 3888f7b5054SVincenzo Frascino #endif /* CONFIG_KASAN_HW_TAGS */ 3898f7b5054SVincenzo Frascino 3902e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS 3912e903b91SAndrey Konovalov void __init kasan_init_sw_tags(void); 3922e903b91SAndrey Konovalov #else 3932e903b91SAndrey Konovalov static inline void kasan_init_sw_tags(void) { } 3942e903b91SAndrey Konovalov #endif 3952e903b91SAndrey Konovalov 3962e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 3972e903b91SAndrey Konovalov void kasan_init_hw_tags_cpu(void); 3982e903b91SAndrey Konovalov void __init kasan_init_hw_tags(void); 3992e903b91SAndrey Konovalov #else 4002e903b91SAndrey Konovalov static inline void kasan_init_hw_tags_cpu(void) { } 4012e903b91SAndrey Konovalov static inline void kasan_init_hw_tags(void) { } 4022e903b91SAndrey Konovalov #endif 403080eb83fSAndrey Konovalov 4043c5c3cfbSDaniel Axtens #ifdef CONFIG_KASAN_VMALLOC 4053b1a4a86SAndrey Konovalov 406*23689e91SAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) 407*23689e91SAndrey Konovalov 4085bd9bae2SAndrey Konovalov void kasan_populate_early_vm_area_shadow(void *start, unsigned long size); 409d98c9e83SAndrey Ryabinin int kasan_populate_vmalloc(unsigned long addr, unsigned long size); 4103c5c3cfbSDaniel Axtens void kasan_release_vmalloc(unsigned long start, unsigned long end, 4113c5c3cfbSDaniel Axtens unsigned long free_region_start, 4123c5c3cfbSDaniel Axtens unsigned long free_region_end); 4133b1a4a86SAndrey Konovalov 414*23689e91SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 415*23689e91SAndrey Konovalov 416*23689e91SAndrey Konovalov static inline void kasan_populate_early_vm_area_shadow(void *start, 417*23689e91SAndrey Konovalov unsigned long size) 418*23689e91SAndrey Konovalov { } 419*23689e91SAndrey Konovalov static inline int kasan_populate_vmalloc(unsigned long start, 420579fb0acSAndrey Konovalov unsigned long size) 421579fb0acSAndrey Konovalov { 422*23689e91SAndrey Konovalov return 0; 423*23689e91SAndrey Konovalov } 424*23689e91SAndrey Konovalov static inline void kasan_release_vmalloc(unsigned long start, 425*23689e91SAndrey Konovalov unsigned long end, 426*23689e91SAndrey Konovalov unsigned long free_region_start, 427*23689e91SAndrey Konovalov unsigned long free_region_end) { } 428*23689e91SAndrey Konovalov 429*23689e91SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 430*23689e91SAndrey Konovalov 431*23689e91SAndrey Konovalov void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, 432*23689e91SAndrey Konovalov kasan_vmalloc_flags_t flags); 433*23689e91SAndrey Konovalov static __always_inline void *kasan_unpoison_vmalloc(const void *start, 434*23689e91SAndrey Konovalov unsigned long size, 435*23689e91SAndrey Konovalov kasan_vmalloc_flags_t flags) 436*23689e91SAndrey Konovalov { 437579fb0acSAndrey Konovalov if (kasan_enabled()) 438*23689e91SAndrey Konovalov return __kasan_unpoison_vmalloc(start, size, flags); 4391d96320fSAndrey Konovalov return (void *)start; 440579fb0acSAndrey Konovalov } 441579fb0acSAndrey Konovalov 442579fb0acSAndrey Konovalov void __kasan_poison_vmalloc(const void *start, unsigned long size); 443579fb0acSAndrey Konovalov static __always_inline void kasan_poison_vmalloc(const void *start, 444579fb0acSAndrey Konovalov unsigned long size) 445579fb0acSAndrey Konovalov { 446579fb0acSAndrey Konovalov if (kasan_enabled()) 447579fb0acSAndrey Konovalov __kasan_poison_vmalloc(start, size); 448579fb0acSAndrey Konovalov } 4493252b1d8SKefeng Wang 4503b1a4a86SAndrey Konovalov #else /* CONFIG_KASAN_VMALLOC */ 4513b1a4a86SAndrey Konovalov 4525bd9bae2SAndrey Konovalov static inline void kasan_populate_early_vm_area_shadow(void *start, 4535bd9bae2SAndrey Konovalov unsigned long size) { } 454d98c9e83SAndrey Ryabinin static inline int kasan_populate_vmalloc(unsigned long start, 455d98c9e83SAndrey Ryabinin unsigned long size) 4563c5c3cfbSDaniel Axtens { 4573c5c3cfbSDaniel Axtens return 0; 4583c5c3cfbSDaniel Axtens } 4593c5c3cfbSDaniel Axtens static inline void kasan_release_vmalloc(unsigned long start, 4603c5c3cfbSDaniel Axtens unsigned long end, 4613c5c3cfbSDaniel Axtens unsigned long free_region_start, 4623c5c3cfbSDaniel Axtens unsigned long free_region_end) { } 4633b1a4a86SAndrey Konovalov 4641d96320fSAndrey Konovalov static inline void *kasan_unpoison_vmalloc(const void *start, 465*23689e91SAndrey Konovalov unsigned long size, 466*23689e91SAndrey Konovalov kasan_vmalloc_flags_t flags) 4671d96320fSAndrey Konovalov { 4681d96320fSAndrey Konovalov return (void *)start; 4691d96320fSAndrey Konovalov } 4705bd9bae2SAndrey Konovalov static inline void kasan_poison_vmalloc(const void *start, unsigned long size) 4713252b1d8SKefeng Wang { } 4723252b1d8SKefeng Wang 4733b1a4a86SAndrey Konovalov #endif /* CONFIG_KASAN_VMALLOC */ 4743b1a4a86SAndrey Konovalov 4750fea6e9aSAndrey Konovalov #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ 4760fea6e9aSAndrey Konovalov !defined(CONFIG_KASAN_VMALLOC) 4773b1a4a86SAndrey Konovalov 4783b1a4a86SAndrey Konovalov /* 47963840de2SAndrey Konovalov * These functions allocate and free shadow memory for kernel modules. 48063840de2SAndrey Konovalov * They are only required when KASAN_VMALLOC is not supported, as otherwise 48163840de2SAndrey Konovalov * shadow memory is allocated by the generic vmalloc handlers. 4823b1a4a86SAndrey Konovalov */ 48363840de2SAndrey Konovalov int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask); 48463840de2SAndrey Konovalov void kasan_free_module_shadow(const struct vm_struct *vm); 4853b1a4a86SAndrey Konovalov 4860fea6e9aSAndrey Konovalov #else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4873b1a4a86SAndrey Konovalov 48863840de2SAndrey Konovalov static inline int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask) { return 0; } 48963840de2SAndrey Konovalov static inline void kasan_free_module_shadow(const struct vm_struct *vm) {} 4903b1a4a86SAndrey Konovalov 4910fea6e9aSAndrey Konovalov #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4923c5c3cfbSDaniel Axtens 4932f004eeaSJann Horn #ifdef CONFIG_KASAN_INLINE 4942f004eeaSJann Horn void kasan_non_canonical_hook(unsigned long addr); 4952f004eeaSJann Horn #else /* CONFIG_KASAN_INLINE */ 4962f004eeaSJann Horn static inline void kasan_non_canonical_hook(unsigned long addr) { } 4972f004eeaSJann Horn #endif /* CONFIG_KASAN_INLINE */ 4982f004eeaSJann Horn 4990b24beccSAndrey Ryabinin #endif /* LINUX_KASAN_H */ 500