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> 6*f9b5e46fSPeter 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 29d5750edfSAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) 30d5750edfSAndrey Konovalov 31d5750edfSAndrey Konovalov #include <linux/pgtable.h> 32d5750edfSAndrey Konovalov 33d5750edfSAndrey Konovalov /* Software KASAN implementations use shadow memory. */ 34d5750edfSAndrey Konovalov 35d5750edfSAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS 36a064cb00SAndrey Konovalov /* This matches KASAN_TAG_INVALID. */ 37a064cb00SAndrey Konovalov #define KASAN_SHADOW_INIT 0xFE 38d5750edfSAndrey Konovalov #else 39d5750edfSAndrey Konovalov #define KASAN_SHADOW_INIT 0 40d5750edfSAndrey Konovalov #endif 41d5750edfSAndrey Konovalov 4229970dc2SHailong Liu #ifndef PTE_HWTABLE_PTRS 4329970dc2SHailong Liu #define PTE_HWTABLE_PTRS 0 4429970dc2SHailong Liu #endif 4529970dc2SHailong Liu 469577dd74SAndrey Konovalov extern unsigned char kasan_early_shadow_page[PAGE_SIZE]; 47cb32c9c5SDaniel Axtens extern pte_t kasan_early_shadow_pte[MAX_PTRS_PER_PTE + PTE_HWTABLE_PTRS]; 48cb32c9c5SDaniel Axtens extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD]; 49cb32c9c5SDaniel Axtens extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD]; 509577dd74SAndrey Konovalov extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D]; 5169786cdbSAndrey Ryabinin 529577dd74SAndrey Konovalov int kasan_populate_early_shadow(const void *shadow_start, 5369786cdbSAndrey Ryabinin const void *shadow_end); 5469786cdbSAndrey Ryabinin 550b24beccSAndrey Ryabinin static inline void *kasan_mem_to_shadow(const void *addr) 560b24beccSAndrey Ryabinin { 570b24beccSAndrey Ryabinin return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) 580b24beccSAndrey Ryabinin + KASAN_SHADOW_OFFSET; 590b24beccSAndrey Ryabinin } 600b24beccSAndrey Ryabinin 61d5750edfSAndrey Konovalov int kasan_add_zero_shadow(void *start, unsigned long size); 62d5750edfSAndrey Konovalov void kasan_remove_zero_shadow(void *start, unsigned long size); 63d5750edfSAndrey Konovalov 64d73b4936SAndrey Konovalov /* Enable reporting bugs after kasan_disable_current() */ 65d73b4936SAndrey Konovalov extern void kasan_enable_current(void); 66d73b4936SAndrey Konovalov 67d73b4936SAndrey Konovalov /* Disable reporting bugs for current task */ 68d73b4936SAndrey Konovalov extern void kasan_disable_current(void); 69d73b4936SAndrey Konovalov 70d5750edfSAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 71d5750edfSAndrey Konovalov 72d5750edfSAndrey Konovalov static inline int kasan_add_zero_shadow(void *start, unsigned long size) 73d5750edfSAndrey Konovalov { 74d5750edfSAndrey Konovalov return 0; 75d5750edfSAndrey Konovalov } 76d5750edfSAndrey Konovalov static inline void kasan_remove_zero_shadow(void *start, 77d5750edfSAndrey Konovalov unsigned long size) 78d5750edfSAndrey Konovalov {} 79d5750edfSAndrey Konovalov 80d73b4936SAndrey Konovalov static inline void kasan_enable_current(void) {} 81d73b4936SAndrey Konovalov static inline void kasan_disable_current(void) {} 82d73b4936SAndrey Konovalov 83d5750edfSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 84d5750edfSAndrey Konovalov 8534303244SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 86e86f8b09SAndrey Konovalov 877a3b8353SPeter Collingbourne void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags); 887a3b8353SPeter Collingbourne void kasan_free_pages(struct page *page, unsigned int order); 897a3b8353SPeter Collingbourne 90e86f8b09SAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */ 91e86f8b09SAndrey Konovalov 927a3b8353SPeter Collingbourne static __always_inline void kasan_alloc_pages(struct page *page, 937a3b8353SPeter Collingbourne unsigned int order, gfp_t flags) 947a3b8353SPeter Collingbourne { 957a3b8353SPeter Collingbourne /* Only available for integrated init. */ 967a3b8353SPeter Collingbourne BUILD_BUG(); 977a3b8353SPeter Collingbourne } 987a3b8353SPeter Collingbourne 997a3b8353SPeter Collingbourne static __always_inline void kasan_free_pages(struct page *page, 1007a3b8353SPeter Collingbourne unsigned int order) 1017a3b8353SPeter Collingbourne { 1027a3b8353SPeter Collingbourne /* Only available for integrated init. */ 1037a3b8353SPeter Collingbourne BUILD_BUG(); 1047a3b8353SPeter Collingbourne } 1057a3b8353SPeter Collingbourne 106e86f8b09SAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */ 107e86f8b09SAndrey Konovalov 108e5af50a5SPeter Collingbourne static inline bool kasan_has_integrated_init(void) 109e5af50a5SPeter Collingbourne { 110e5af50a5SPeter Collingbourne return kasan_hw_tags_enabled(); 111e5af50a5SPeter Collingbourne } 112e5af50a5SPeter Collingbourne 1137a3b8353SPeter Collingbourne #ifdef CONFIG_KASAN 1147a3b8353SPeter Collingbourne 1157a3b8353SPeter Collingbourne struct kasan_cache { 1167a3b8353SPeter Collingbourne int alloc_meta_offset; 1177a3b8353SPeter Collingbourne int free_meta_offset; 1187a3b8353SPeter Collingbourne bool is_kmalloc; 1197a3b8353SPeter Collingbourne }; 1207a3b8353SPeter Collingbourne 121e86f8b09SAndrey Konovalov slab_flags_t __kasan_never_merge(void); 122e86f8b09SAndrey Konovalov static __always_inline slab_flags_t kasan_never_merge(void) 123e86f8b09SAndrey Konovalov { 124e86f8b09SAndrey Konovalov if (kasan_enabled()) 125e86f8b09SAndrey Konovalov return __kasan_never_merge(); 126e86f8b09SAndrey Konovalov return 0; 127e86f8b09SAndrey Konovalov } 12834303244SAndrey Konovalov 12934303244SAndrey Konovalov void __kasan_unpoison_range(const void *addr, size_t size); 13034303244SAndrey Konovalov static __always_inline void kasan_unpoison_range(const void *addr, size_t size) 13134303244SAndrey Konovalov { 13234303244SAndrey Konovalov if (kasan_enabled()) 13334303244SAndrey Konovalov __kasan_unpoison_range(addr, size); 13434303244SAndrey Konovalov } 13534303244SAndrey Konovalov 1367a3b8353SPeter Collingbourne void __kasan_poison_pages(struct page *page, unsigned int order, bool init); 1377a3b8353SPeter Collingbourne static __always_inline void kasan_poison_pages(struct page *page, 1381bb5eab3SAndrey Konovalov unsigned int order, bool init) 13934303244SAndrey Konovalov { 14034303244SAndrey Konovalov if (kasan_enabled()) 1417a3b8353SPeter Collingbourne __kasan_poison_pages(page, order, init); 14234303244SAndrey Konovalov } 14334303244SAndrey Konovalov 1447a3b8353SPeter Collingbourne void __kasan_unpoison_pages(struct page *page, unsigned int order, bool init); 1457a3b8353SPeter Collingbourne static __always_inline void kasan_unpoison_pages(struct page *page, 1461bb5eab3SAndrey Konovalov unsigned int order, bool init) 14734303244SAndrey Konovalov { 14834303244SAndrey Konovalov if (kasan_enabled()) 1497a3b8353SPeter Collingbourne __kasan_unpoison_pages(page, order, init); 15034303244SAndrey Konovalov } 15134303244SAndrey Konovalov 15234303244SAndrey Konovalov void __kasan_cache_create(struct kmem_cache *cache, unsigned int *size, 15334303244SAndrey Konovalov slab_flags_t *flags); 15434303244SAndrey Konovalov static __always_inline void kasan_cache_create(struct kmem_cache *cache, 15534303244SAndrey Konovalov unsigned int *size, slab_flags_t *flags) 15634303244SAndrey Konovalov { 15734303244SAndrey Konovalov if (kasan_enabled()) 15834303244SAndrey Konovalov __kasan_cache_create(cache, size, flags); 15934303244SAndrey Konovalov } 16034303244SAndrey Konovalov 16192850134SAndrey Konovalov void __kasan_cache_create_kmalloc(struct kmem_cache *cache); 16292850134SAndrey Konovalov static __always_inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) 16392850134SAndrey Konovalov { 16492850134SAndrey Konovalov if (kasan_enabled()) 16592850134SAndrey Konovalov __kasan_cache_create_kmalloc(cache); 16692850134SAndrey Konovalov } 16792850134SAndrey Konovalov 16834303244SAndrey Konovalov size_t __kasan_metadata_size(struct kmem_cache *cache); 16934303244SAndrey Konovalov static __always_inline size_t kasan_metadata_size(struct kmem_cache *cache) 17034303244SAndrey Konovalov { 17134303244SAndrey Konovalov if (kasan_enabled()) 17234303244SAndrey Konovalov return __kasan_metadata_size(cache); 17334303244SAndrey Konovalov return 0; 17434303244SAndrey Konovalov } 17534303244SAndrey Konovalov 1766e48a966SMatthew Wilcox (Oracle) void __kasan_poison_slab(struct slab *slab); 1776e48a966SMatthew Wilcox (Oracle) static __always_inline void kasan_poison_slab(struct slab *slab) 17834303244SAndrey Konovalov { 17934303244SAndrey Konovalov if (kasan_enabled()) 1806e48a966SMatthew Wilcox (Oracle) __kasan_poison_slab(slab); 18134303244SAndrey Konovalov } 18234303244SAndrey Konovalov 18334303244SAndrey Konovalov void __kasan_unpoison_object_data(struct kmem_cache *cache, void *object); 18434303244SAndrey Konovalov static __always_inline void kasan_unpoison_object_data(struct kmem_cache *cache, 18534303244SAndrey Konovalov void *object) 18634303244SAndrey Konovalov { 18734303244SAndrey Konovalov if (kasan_enabled()) 18834303244SAndrey Konovalov __kasan_unpoison_object_data(cache, object); 18934303244SAndrey Konovalov } 19034303244SAndrey Konovalov 19134303244SAndrey Konovalov void __kasan_poison_object_data(struct kmem_cache *cache, void *object); 19234303244SAndrey Konovalov static __always_inline void kasan_poison_object_data(struct kmem_cache *cache, 19334303244SAndrey Konovalov void *object) 19434303244SAndrey Konovalov { 19534303244SAndrey Konovalov if (kasan_enabled()) 19634303244SAndrey Konovalov __kasan_poison_object_data(cache, object); 19734303244SAndrey Konovalov } 19834303244SAndrey Konovalov 19934303244SAndrey Konovalov void * __must_check __kasan_init_slab_obj(struct kmem_cache *cache, 20034303244SAndrey Konovalov const void *object); 20134303244SAndrey Konovalov static __always_inline void * __must_check kasan_init_slab_obj( 20234303244SAndrey Konovalov struct kmem_cache *cache, const void *object) 20334303244SAndrey Konovalov { 20434303244SAndrey Konovalov if (kasan_enabled()) 20534303244SAndrey Konovalov return __kasan_init_slab_obj(cache, object); 20634303244SAndrey Konovalov return (void *)object; 20734303244SAndrey Konovalov } 20834303244SAndrey Konovalov 209d57a964eSAndrey Konovalov bool __kasan_slab_free(struct kmem_cache *s, void *object, 210d57a964eSAndrey Konovalov unsigned long ip, bool init); 211d57a964eSAndrey Konovalov static __always_inline bool kasan_slab_free(struct kmem_cache *s, 212d57a964eSAndrey Konovalov void *object, bool init) 21334303244SAndrey Konovalov { 21434303244SAndrey Konovalov if (kasan_enabled()) 215d57a964eSAndrey Konovalov return __kasan_slab_free(s, object, _RET_IP_, init); 21634303244SAndrey Konovalov return false; 21734303244SAndrey Konovalov } 21834303244SAndrey Konovalov 219200072ceSAndrey Konovalov void __kasan_kfree_large(void *ptr, unsigned long ip); 220200072ceSAndrey Konovalov static __always_inline void kasan_kfree_large(void *ptr) 221200072ceSAndrey Konovalov { 222200072ceSAndrey Konovalov if (kasan_enabled()) 223200072ceSAndrey Konovalov __kasan_kfree_large(ptr, _RET_IP_); 224200072ceSAndrey Konovalov } 225200072ceSAndrey Konovalov 226eeb3160cSAndrey Konovalov void __kasan_slab_free_mempool(void *ptr, unsigned long ip); 227027b37b5SAndrey Konovalov static __always_inline void kasan_slab_free_mempool(void *ptr) 228eeb3160cSAndrey Konovalov { 229eeb3160cSAndrey Konovalov if (kasan_enabled()) 230027b37b5SAndrey Konovalov __kasan_slab_free_mempool(ptr, _RET_IP_); 231eeb3160cSAndrey Konovalov } 232eeb3160cSAndrey Konovalov 23334303244SAndrey Konovalov void * __must_check __kasan_slab_alloc(struct kmem_cache *s, 234da844b78SAndrey Konovalov void *object, gfp_t flags, bool init); 23534303244SAndrey Konovalov static __always_inline void * __must_check kasan_slab_alloc( 236da844b78SAndrey Konovalov struct kmem_cache *s, void *object, gfp_t flags, bool init) 23734303244SAndrey Konovalov { 23834303244SAndrey Konovalov if (kasan_enabled()) 239da844b78SAndrey Konovalov return __kasan_slab_alloc(s, object, flags, init); 24034303244SAndrey Konovalov return object; 24134303244SAndrey Konovalov } 24234303244SAndrey Konovalov 24334303244SAndrey Konovalov void * __must_check __kasan_kmalloc(struct kmem_cache *s, const void *object, 24434303244SAndrey Konovalov size_t size, gfp_t flags); 24534303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc(struct kmem_cache *s, 24634303244SAndrey Konovalov const void *object, size_t size, gfp_t flags) 24734303244SAndrey Konovalov { 24834303244SAndrey Konovalov if (kasan_enabled()) 24934303244SAndrey Konovalov return __kasan_kmalloc(s, object, size, flags); 25034303244SAndrey Konovalov return (void *)object; 25134303244SAndrey Konovalov } 25234303244SAndrey Konovalov 25334303244SAndrey Konovalov void * __must_check __kasan_kmalloc_large(const void *ptr, 25434303244SAndrey Konovalov size_t size, gfp_t flags); 25534303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc_large(const void *ptr, 25634303244SAndrey Konovalov size_t size, gfp_t flags) 25734303244SAndrey Konovalov { 25834303244SAndrey Konovalov if (kasan_enabled()) 25934303244SAndrey Konovalov return __kasan_kmalloc_large(ptr, size, flags); 26034303244SAndrey Konovalov return (void *)ptr; 26134303244SAndrey Konovalov } 26234303244SAndrey Konovalov 26334303244SAndrey Konovalov void * __must_check __kasan_krealloc(const void *object, 26434303244SAndrey Konovalov size_t new_size, gfp_t flags); 26534303244SAndrey Konovalov static __always_inline void * __must_check kasan_krealloc(const void *object, 26634303244SAndrey Konovalov size_t new_size, gfp_t flags) 26734303244SAndrey Konovalov { 26834303244SAndrey Konovalov if (kasan_enabled()) 26934303244SAndrey Konovalov return __kasan_krealloc(object, new_size, flags); 27034303244SAndrey Konovalov return (void *)object; 27134303244SAndrey Konovalov } 27234303244SAndrey Konovalov 273611806b4SAndrey Konovalov /* 274611806b4SAndrey Konovalov * Unlike kasan_check_read/write(), kasan_check_byte() is performed even for 275611806b4SAndrey Konovalov * the hardware tag-based mode that doesn't rely on compiler instrumentation. 276611806b4SAndrey Konovalov */ 277611806b4SAndrey Konovalov bool __kasan_check_byte(const void *addr, unsigned long ip); 278611806b4SAndrey Konovalov static __always_inline bool kasan_check_byte(const void *addr) 279611806b4SAndrey Konovalov { 280611806b4SAndrey Konovalov if (kasan_enabled()) 281611806b4SAndrey Konovalov return __kasan_check_byte(addr, _RET_IP_); 282611806b4SAndrey Konovalov return true; 283611806b4SAndrey Konovalov } 284611806b4SAndrey Konovalov 285611806b4SAndrey Konovalov 286b0845ce5SMark Rutland bool kasan_save_enable_multi_shot(void); 287b0845ce5SMark Rutland void kasan_restore_multi_shot(bool enabled); 288b0845ce5SMark Rutland 2890b24beccSAndrey Ryabinin #else /* CONFIG_KASAN */ 2900b24beccSAndrey Ryabinin 291e86f8b09SAndrey Konovalov static inline slab_flags_t kasan_never_merge(void) 292e86f8b09SAndrey Konovalov { 293e86f8b09SAndrey Konovalov return 0; 294e86f8b09SAndrey Konovalov } 295cebd0eb2SAndrey Konovalov static inline void kasan_unpoison_range(const void *address, size_t size) {} 2967a3b8353SPeter Collingbourne static inline void kasan_poison_pages(struct page *page, unsigned int order, 2977a3b8353SPeter Collingbourne bool init) {} 2987a3b8353SPeter Collingbourne static inline void kasan_unpoison_pages(struct page *page, unsigned int order, 2997a3b8353SPeter Collingbourne bool init) {} 3007ed2f9e6SAlexander Potapenko static inline void kasan_cache_create(struct kmem_cache *cache, 301be4a7988SAlexey Dobriyan unsigned int *size, 302d50112edSAlexey Dobriyan slab_flags_t *flags) {} 30392850134SAndrey Konovalov static inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) {} 30434303244SAndrey Konovalov static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; } 3056e48a966SMatthew Wilcox (Oracle) static inline void kasan_poison_slab(struct slab *slab) {} 3060316bec2SAndrey Ryabinin static inline void kasan_unpoison_object_data(struct kmem_cache *cache, 3070316bec2SAndrey Ryabinin void *object) {} 3080316bec2SAndrey Ryabinin static inline void kasan_poison_object_data(struct kmem_cache *cache, 3090316bec2SAndrey Ryabinin void *object) {} 3100116523cSAndrey Konovalov static inline void *kasan_init_slab_obj(struct kmem_cache *cache, 3110116523cSAndrey Konovalov const void *object) 3120116523cSAndrey Konovalov { 3130116523cSAndrey Konovalov return (void *)object; 3140116523cSAndrey Konovalov } 315d57a964eSAndrey Konovalov static inline bool kasan_slab_free(struct kmem_cache *s, void *object, bool init) 3160116523cSAndrey Konovalov { 31734303244SAndrey Konovalov return false; 3180116523cSAndrey Konovalov } 319200072ceSAndrey Konovalov static inline void kasan_kfree_large(void *ptr) {} 320027b37b5SAndrey Konovalov static inline void kasan_slab_free_mempool(void *ptr) {} 32134303244SAndrey Konovalov static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object, 322da844b78SAndrey Konovalov gfp_t flags, bool init) 32334303244SAndrey Konovalov { 32434303244SAndrey Konovalov return object; 32534303244SAndrey Konovalov } 3260116523cSAndrey Konovalov static inline void *kasan_kmalloc(struct kmem_cache *s, const void *object, 3270116523cSAndrey Konovalov size_t size, gfp_t flags) 3280116523cSAndrey Konovalov { 3290116523cSAndrey Konovalov return (void *)object; 3300116523cSAndrey Konovalov } 33134303244SAndrey Konovalov static inline void *kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags) 33234303244SAndrey Konovalov { 33334303244SAndrey Konovalov return (void *)ptr; 33434303244SAndrey Konovalov } 3350116523cSAndrey Konovalov static inline void *kasan_krealloc(const void *object, size_t new_size, 3360116523cSAndrey Konovalov gfp_t flags) 3370116523cSAndrey Konovalov { 3380116523cSAndrey Konovalov return (void *)object; 3390116523cSAndrey Konovalov } 340611806b4SAndrey Konovalov static inline bool kasan_check_byte(const void *address) 341611806b4SAndrey Konovalov { 342611806b4SAndrey Konovalov return true; 343611806b4SAndrey Konovalov } 3449b75a867SAndrey Ryabinin 3450b24beccSAndrey Ryabinin #endif /* CONFIG_KASAN */ 3460b24beccSAndrey Ryabinin 34702c58773SWalter Wu #if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK) 348d56a9ef8SAndrey Konovalov void kasan_unpoison_task_stack(struct task_struct *task); 349d56a9ef8SAndrey Konovalov #else 350d56a9ef8SAndrey Konovalov static inline void kasan_unpoison_task_stack(struct task_struct *task) {} 351d56a9ef8SAndrey Konovalov #endif 352d56a9ef8SAndrey Konovalov 3532bd926b4SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC 3542bd926b4SAndrey Konovalov 3552bd926b4SAndrey Konovalov void kasan_cache_shrink(struct kmem_cache *cache); 3562bd926b4SAndrey Konovalov void kasan_cache_shutdown(struct kmem_cache *cache); 35726e760c9SWalter Wu void kasan_record_aux_stack(void *ptr); 3587cb3007cSMarco Elver void kasan_record_aux_stack_noalloc(void *ptr); 3592bd926b4SAndrey Konovalov 3602bd926b4SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC */ 3612bd926b4SAndrey Konovalov 3622bd926b4SAndrey Konovalov static inline void kasan_cache_shrink(struct kmem_cache *cache) {} 3632bd926b4SAndrey Konovalov static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} 36426e760c9SWalter Wu static inline void kasan_record_aux_stack(void *ptr) {} 3657cb3007cSMarco Elver static inline void kasan_record_aux_stack_noalloc(void *ptr) {} 3662bd926b4SAndrey Konovalov 3672bd926b4SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */ 3682bd926b4SAndrey Konovalov 3692e903b91SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) 3703c9e3aa1SAndrey Konovalov 371c0054c56SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 372c0054c56SAndrey Konovalov { 373c0054c56SAndrey Konovalov return (void *)arch_kasan_reset_tag(addr); 374c0054c56SAndrey Konovalov } 3753c9e3aa1SAndrey Konovalov 37649c6631dSVincenzo Frascino /** 37749c6631dSVincenzo Frascino * kasan_report - print a report about a bad memory access detected by KASAN 37849c6631dSVincenzo Frascino * @addr: address of the bad access 37949c6631dSVincenzo Frascino * @size: size of the bad access 38049c6631dSVincenzo Frascino * @is_write: whether the bad access is a write or a read 38149c6631dSVincenzo Frascino * @ip: instruction pointer for the accessibility check or the bad access itself 38249c6631dSVincenzo Frascino */ 3838cceeff4SWalter Wu bool kasan_report(unsigned long addr, size_t size, 38441eea9cdSAndrey Konovalov bool is_write, unsigned long ip); 38541eea9cdSAndrey Konovalov 3862e903b91SAndrey Konovalov #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */ 3873c9e3aa1SAndrey Konovalov 3883c9e3aa1SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 3893c9e3aa1SAndrey Konovalov { 3903c9e3aa1SAndrey Konovalov return (void *)addr; 3913c9e3aa1SAndrey Konovalov } 3923c9e3aa1SAndrey Konovalov 3932e903b91SAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS*/ 3942e903b91SAndrey Konovalov 3958f7b5054SVincenzo Frascino #ifdef CONFIG_KASAN_HW_TAGS 3968f7b5054SVincenzo Frascino 3978f7b5054SVincenzo Frascino void kasan_report_async(void); 3988f7b5054SVincenzo Frascino 3998f7b5054SVincenzo Frascino #endif /* CONFIG_KASAN_HW_TAGS */ 4008f7b5054SVincenzo Frascino 4012e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS 4022e903b91SAndrey Konovalov void __init kasan_init_sw_tags(void); 4032e903b91SAndrey Konovalov #else 4042e903b91SAndrey Konovalov static inline void kasan_init_sw_tags(void) { } 4052e903b91SAndrey Konovalov #endif 4062e903b91SAndrey Konovalov 4072e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 4082e903b91SAndrey Konovalov void kasan_init_hw_tags_cpu(void); 4092e903b91SAndrey Konovalov void __init kasan_init_hw_tags(void); 4102e903b91SAndrey Konovalov #else 4112e903b91SAndrey Konovalov static inline void kasan_init_hw_tags_cpu(void) { } 4122e903b91SAndrey Konovalov static inline void kasan_init_hw_tags(void) { } 4132e903b91SAndrey Konovalov #endif 414080eb83fSAndrey Konovalov 4153c5c3cfbSDaniel Axtens #ifdef CONFIG_KASAN_VMALLOC 4163b1a4a86SAndrey Konovalov 417d98c9e83SAndrey Ryabinin int kasan_populate_vmalloc(unsigned long addr, unsigned long size); 418d98c9e83SAndrey Ryabinin void kasan_poison_vmalloc(const void *start, unsigned long size); 419d98c9e83SAndrey Ryabinin void kasan_unpoison_vmalloc(const void *start, unsigned long size); 4203c5c3cfbSDaniel Axtens void kasan_release_vmalloc(unsigned long start, unsigned long end, 4213c5c3cfbSDaniel Axtens unsigned long free_region_start, 4223c5c3cfbSDaniel Axtens unsigned long free_region_end); 4233b1a4a86SAndrey Konovalov 4243252b1d8SKefeng Wang void kasan_populate_early_vm_area_shadow(void *start, unsigned long size); 4253252b1d8SKefeng Wang 4263b1a4a86SAndrey Konovalov #else /* CONFIG_KASAN_VMALLOC */ 4273b1a4a86SAndrey Konovalov 428d98c9e83SAndrey Ryabinin static inline int kasan_populate_vmalloc(unsigned long start, 429d98c9e83SAndrey Ryabinin unsigned long size) 4303c5c3cfbSDaniel Axtens { 4313c5c3cfbSDaniel Axtens return 0; 4323c5c3cfbSDaniel Axtens } 4333c5c3cfbSDaniel Axtens 434d98c9e83SAndrey Ryabinin static inline void kasan_poison_vmalloc(const void *start, unsigned long size) 435d98c9e83SAndrey Ryabinin { } 436d98c9e83SAndrey Ryabinin static inline void kasan_unpoison_vmalloc(const void *start, unsigned long size) 437d98c9e83SAndrey Ryabinin { } 4383c5c3cfbSDaniel Axtens static inline void kasan_release_vmalloc(unsigned long start, 4393c5c3cfbSDaniel Axtens unsigned long end, 4403c5c3cfbSDaniel Axtens unsigned long free_region_start, 4413c5c3cfbSDaniel Axtens unsigned long free_region_end) {} 4423b1a4a86SAndrey Konovalov 4433252b1d8SKefeng Wang static inline void kasan_populate_early_vm_area_shadow(void *start, 4443252b1d8SKefeng Wang unsigned long size) 4453252b1d8SKefeng Wang { } 4463252b1d8SKefeng Wang 4473b1a4a86SAndrey Konovalov #endif /* CONFIG_KASAN_VMALLOC */ 4483b1a4a86SAndrey Konovalov 4490fea6e9aSAndrey Konovalov #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ 4500fea6e9aSAndrey Konovalov !defined(CONFIG_KASAN_VMALLOC) 4513b1a4a86SAndrey Konovalov 4523b1a4a86SAndrey Konovalov /* 4533b1a4a86SAndrey Konovalov * These functions provide a special case to support backing module 4543b1a4a86SAndrey Konovalov * allocations with real shadow memory. With KASAN vmalloc, the special 4553b1a4a86SAndrey Konovalov * case is unnecessary, as the work is handled in the generic case. 4563b1a4a86SAndrey Konovalov */ 45760115fa5SKefeng Wang int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask); 4583b1a4a86SAndrey Konovalov void kasan_free_shadow(const struct vm_struct *vm); 4593b1a4a86SAndrey Konovalov 4600fea6e9aSAndrey Konovalov #else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4613b1a4a86SAndrey Konovalov 46260115fa5SKefeng Wang static inline int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask) { return 0; } 4633b1a4a86SAndrey Konovalov static inline void kasan_free_shadow(const struct vm_struct *vm) {} 4643b1a4a86SAndrey Konovalov 4650fea6e9aSAndrey Konovalov #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4663c5c3cfbSDaniel Axtens 4672f004eeaSJann Horn #ifdef CONFIG_KASAN_INLINE 4682f004eeaSJann Horn void kasan_non_canonical_hook(unsigned long addr); 4692f004eeaSJann Horn #else /* CONFIG_KASAN_INLINE */ 4702f004eeaSJann Horn static inline void kasan_non_canonical_hook(unsigned long addr) { } 4712f004eeaSJann Horn #endif /* CONFIG_KASAN_INLINE */ 4722f004eeaSJann Horn 4730b24beccSAndrey Ryabinin #endif /* LINUX_KASAN_H */ 474