1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 20b24beccSAndrey Ryabinin #ifndef _LINUX_KASAN_H 30b24beccSAndrey Ryabinin #define _LINUX_KASAN_H 40b24beccSAndrey Ryabinin 534303244SAndrey Konovalov #include <linux/static_key.h> 60b24beccSAndrey Ryabinin #include <linux/types.h> 70b24beccSAndrey Ryabinin 80b24beccSAndrey Ryabinin struct kmem_cache; 90b24beccSAndrey Ryabinin struct page; 10a5af5aa8SAndrey Ryabinin struct vm_struct; 115be9b730SMasami Hiramatsu struct task_struct; 120b24beccSAndrey Ryabinin 130b24beccSAndrey Ryabinin #ifdef CONFIG_KASAN 140b24beccSAndrey Ryabinin 15d5750edfSAndrey Konovalov #include <linux/linkage.h> 1665fddcfcSMike Rapoport #include <asm/kasan.h> 170b24beccSAndrey Ryabinin 1883c4e7a0SPatricia Alfonso /* kasan_data struct is used in KUnit tests for KASAN expected failures */ 1983c4e7a0SPatricia Alfonso struct kunit_kasan_expectation { 2083c4e7a0SPatricia Alfonso bool report_expected; 2183c4e7a0SPatricia Alfonso bool report_found; 2283c4e7a0SPatricia Alfonso }; 2383c4e7a0SPatricia Alfonso 24d5750edfSAndrey Konovalov #endif 25d5750edfSAndrey Konovalov 26d5750edfSAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) 27d5750edfSAndrey Konovalov 28d5750edfSAndrey Konovalov #include <linux/pgtable.h> 29d5750edfSAndrey Konovalov 30d5750edfSAndrey Konovalov /* Software KASAN implementations use shadow memory. */ 31d5750edfSAndrey Konovalov 32d5750edfSAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS 33d5750edfSAndrey Konovalov #define KASAN_SHADOW_INIT 0xFF 34d5750edfSAndrey Konovalov #else 35d5750edfSAndrey Konovalov #define KASAN_SHADOW_INIT 0 36d5750edfSAndrey Konovalov #endif 37d5750edfSAndrey Konovalov 3829970dc2SHailong Liu #ifndef PTE_HWTABLE_PTRS 3929970dc2SHailong Liu #define PTE_HWTABLE_PTRS 0 4029970dc2SHailong Liu #endif 4129970dc2SHailong Liu 429577dd74SAndrey Konovalov extern unsigned char kasan_early_shadow_page[PAGE_SIZE]; 4329970dc2SHailong Liu extern pte_t kasan_early_shadow_pte[PTRS_PER_PTE + PTE_HWTABLE_PTRS]; 449577dd74SAndrey Konovalov extern pmd_t kasan_early_shadow_pmd[PTRS_PER_PMD]; 459577dd74SAndrey Konovalov extern pud_t kasan_early_shadow_pud[PTRS_PER_PUD]; 469577dd74SAndrey Konovalov extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D]; 4769786cdbSAndrey Ryabinin 489577dd74SAndrey Konovalov int kasan_populate_early_shadow(const void *shadow_start, 4969786cdbSAndrey Ryabinin const void *shadow_end); 5069786cdbSAndrey Ryabinin 510b24beccSAndrey Ryabinin static inline void *kasan_mem_to_shadow(const void *addr) 520b24beccSAndrey Ryabinin { 530b24beccSAndrey Ryabinin return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) 540b24beccSAndrey Ryabinin + KASAN_SHADOW_OFFSET; 550b24beccSAndrey Ryabinin } 560b24beccSAndrey Ryabinin 57d5750edfSAndrey Konovalov int kasan_add_zero_shadow(void *start, unsigned long size); 58d5750edfSAndrey Konovalov void kasan_remove_zero_shadow(void *start, unsigned long size); 59d5750edfSAndrey Konovalov 60d73b4936SAndrey Konovalov /* Enable reporting bugs after kasan_disable_current() */ 61d73b4936SAndrey Konovalov extern void kasan_enable_current(void); 62d73b4936SAndrey Konovalov 63d73b4936SAndrey Konovalov /* Disable reporting bugs for current task */ 64d73b4936SAndrey Konovalov extern void kasan_disable_current(void); 65d73b4936SAndrey Konovalov 66d5750edfSAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 67d5750edfSAndrey Konovalov 68d5750edfSAndrey Konovalov static inline int kasan_add_zero_shadow(void *start, unsigned long size) 69d5750edfSAndrey Konovalov { 70d5750edfSAndrey Konovalov return 0; 71d5750edfSAndrey Konovalov } 72d5750edfSAndrey Konovalov static inline void kasan_remove_zero_shadow(void *start, 73d5750edfSAndrey Konovalov unsigned long size) 74d5750edfSAndrey Konovalov {} 75d5750edfSAndrey Konovalov 76d73b4936SAndrey Konovalov static inline void kasan_enable_current(void) {} 77d73b4936SAndrey Konovalov static inline void kasan_disable_current(void) {} 78d73b4936SAndrey Konovalov 79d5750edfSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 80d5750edfSAndrey Konovalov 81d5750edfSAndrey Konovalov #ifdef CONFIG_KASAN 82d5750edfSAndrey Konovalov 837ed2f9e6SAlexander Potapenko struct kasan_cache { 847ed2f9e6SAlexander Potapenko int alloc_meta_offset; 857ed2f9e6SAlexander Potapenko int free_meta_offset; 86*92850134SAndrey Konovalov bool is_kmalloc; 877ed2f9e6SAlexander Potapenko }; 887ed2f9e6SAlexander Potapenko 8934303244SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 90e86f8b09SAndrey Konovalov 9134303244SAndrey Konovalov DECLARE_STATIC_KEY_FALSE(kasan_flag_enabled); 92e86f8b09SAndrey Konovalov 9334303244SAndrey Konovalov static __always_inline bool kasan_enabled(void) 9434303244SAndrey Konovalov { 9534303244SAndrey Konovalov return static_branch_likely(&kasan_flag_enabled); 9634303244SAndrey Konovalov } 97e86f8b09SAndrey Konovalov 98e86f8b09SAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */ 99e86f8b09SAndrey Konovalov 10034303244SAndrey Konovalov static inline bool kasan_enabled(void) 10134303244SAndrey Konovalov { 10234303244SAndrey Konovalov return true; 10334303244SAndrey Konovalov } 104e86f8b09SAndrey Konovalov 105e86f8b09SAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */ 106e86f8b09SAndrey Konovalov 107e86f8b09SAndrey Konovalov slab_flags_t __kasan_never_merge(void); 108e86f8b09SAndrey Konovalov static __always_inline slab_flags_t kasan_never_merge(void) 109e86f8b09SAndrey Konovalov { 110e86f8b09SAndrey Konovalov if (kasan_enabled()) 111e86f8b09SAndrey Konovalov return __kasan_never_merge(); 112e86f8b09SAndrey Konovalov return 0; 113e86f8b09SAndrey Konovalov } 11434303244SAndrey Konovalov 11534303244SAndrey Konovalov void __kasan_unpoison_range(const void *addr, size_t size); 11634303244SAndrey Konovalov static __always_inline void kasan_unpoison_range(const void *addr, size_t size) 11734303244SAndrey Konovalov { 11834303244SAndrey Konovalov if (kasan_enabled()) 11934303244SAndrey Konovalov __kasan_unpoison_range(addr, size); 12034303244SAndrey Konovalov } 12134303244SAndrey Konovalov 12234303244SAndrey Konovalov void __kasan_alloc_pages(struct page *page, unsigned int order); 12334303244SAndrey Konovalov static __always_inline void kasan_alloc_pages(struct page *page, 12434303244SAndrey Konovalov unsigned int order) 12534303244SAndrey Konovalov { 12634303244SAndrey Konovalov if (kasan_enabled()) 12734303244SAndrey Konovalov __kasan_alloc_pages(page, order); 12834303244SAndrey Konovalov } 12934303244SAndrey Konovalov 13034303244SAndrey Konovalov void __kasan_free_pages(struct page *page, unsigned int order); 13134303244SAndrey Konovalov static __always_inline void kasan_free_pages(struct page *page, 13234303244SAndrey Konovalov unsigned int order) 13334303244SAndrey Konovalov { 13434303244SAndrey Konovalov if (kasan_enabled()) 13534303244SAndrey Konovalov __kasan_free_pages(page, order); 13634303244SAndrey Konovalov } 13734303244SAndrey Konovalov 13834303244SAndrey Konovalov void __kasan_cache_create(struct kmem_cache *cache, unsigned int *size, 13934303244SAndrey Konovalov slab_flags_t *flags); 14034303244SAndrey Konovalov static __always_inline void kasan_cache_create(struct kmem_cache *cache, 14134303244SAndrey Konovalov unsigned int *size, slab_flags_t *flags) 14234303244SAndrey Konovalov { 14334303244SAndrey Konovalov if (kasan_enabled()) 14434303244SAndrey Konovalov __kasan_cache_create(cache, size, flags); 14534303244SAndrey Konovalov } 14634303244SAndrey Konovalov 147*92850134SAndrey Konovalov void __kasan_cache_create_kmalloc(struct kmem_cache *cache); 148*92850134SAndrey Konovalov static __always_inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) 149*92850134SAndrey Konovalov { 150*92850134SAndrey Konovalov if (kasan_enabled()) 151*92850134SAndrey Konovalov __kasan_cache_create_kmalloc(cache); 152*92850134SAndrey Konovalov } 153*92850134SAndrey Konovalov 15434303244SAndrey Konovalov size_t __kasan_metadata_size(struct kmem_cache *cache); 15534303244SAndrey Konovalov static __always_inline size_t kasan_metadata_size(struct kmem_cache *cache) 15634303244SAndrey Konovalov { 15734303244SAndrey Konovalov if (kasan_enabled()) 15834303244SAndrey Konovalov return __kasan_metadata_size(cache); 15934303244SAndrey Konovalov return 0; 16034303244SAndrey Konovalov } 16134303244SAndrey Konovalov 16234303244SAndrey Konovalov void __kasan_poison_slab(struct page *page); 16334303244SAndrey Konovalov static __always_inline void kasan_poison_slab(struct page *page) 16434303244SAndrey Konovalov { 16534303244SAndrey Konovalov if (kasan_enabled()) 16634303244SAndrey Konovalov __kasan_poison_slab(page); 16734303244SAndrey Konovalov } 16834303244SAndrey Konovalov 16934303244SAndrey Konovalov void __kasan_unpoison_object_data(struct kmem_cache *cache, void *object); 17034303244SAndrey Konovalov static __always_inline void kasan_unpoison_object_data(struct kmem_cache *cache, 17134303244SAndrey Konovalov void *object) 17234303244SAndrey Konovalov { 17334303244SAndrey Konovalov if (kasan_enabled()) 17434303244SAndrey Konovalov __kasan_unpoison_object_data(cache, object); 17534303244SAndrey Konovalov } 17634303244SAndrey Konovalov 17734303244SAndrey Konovalov void __kasan_poison_object_data(struct kmem_cache *cache, void *object); 17834303244SAndrey Konovalov static __always_inline void kasan_poison_object_data(struct kmem_cache *cache, 17934303244SAndrey Konovalov void *object) 18034303244SAndrey Konovalov { 18134303244SAndrey Konovalov if (kasan_enabled()) 18234303244SAndrey Konovalov __kasan_poison_object_data(cache, object); 18334303244SAndrey Konovalov } 18434303244SAndrey Konovalov 18534303244SAndrey Konovalov void * __must_check __kasan_init_slab_obj(struct kmem_cache *cache, 18634303244SAndrey Konovalov const void *object); 18734303244SAndrey Konovalov static __always_inline void * __must_check kasan_init_slab_obj( 18834303244SAndrey Konovalov struct kmem_cache *cache, const void *object) 18934303244SAndrey Konovalov { 19034303244SAndrey Konovalov if (kasan_enabled()) 19134303244SAndrey Konovalov return __kasan_init_slab_obj(cache, object); 19234303244SAndrey Konovalov return (void *)object; 19334303244SAndrey Konovalov } 19434303244SAndrey Konovalov 19534303244SAndrey Konovalov bool __kasan_slab_free(struct kmem_cache *s, void *object, unsigned long ip); 196027b37b5SAndrey Konovalov static __always_inline bool kasan_slab_free(struct kmem_cache *s, void *object) 19734303244SAndrey Konovalov { 19834303244SAndrey Konovalov if (kasan_enabled()) 199027b37b5SAndrey Konovalov return __kasan_slab_free(s, object, _RET_IP_); 20034303244SAndrey Konovalov return false; 20134303244SAndrey Konovalov } 20234303244SAndrey Konovalov 203eeb3160cSAndrey Konovalov void __kasan_slab_free_mempool(void *ptr, unsigned long ip); 204027b37b5SAndrey Konovalov static __always_inline void kasan_slab_free_mempool(void *ptr) 205eeb3160cSAndrey Konovalov { 206eeb3160cSAndrey Konovalov if (kasan_enabled()) 207027b37b5SAndrey Konovalov __kasan_slab_free_mempool(ptr, _RET_IP_); 208eeb3160cSAndrey Konovalov } 209eeb3160cSAndrey Konovalov 21034303244SAndrey Konovalov void * __must_check __kasan_slab_alloc(struct kmem_cache *s, 21134303244SAndrey Konovalov void *object, gfp_t flags); 21234303244SAndrey Konovalov static __always_inline void * __must_check kasan_slab_alloc( 21334303244SAndrey Konovalov struct kmem_cache *s, void *object, gfp_t flags) 21434303244SAndrey Konovalov { 21534303244SAndrey Konovalov if (kasan_enabled()) 21634303244SAndrey Konovalov return __kasan_slab_alloc(s, object, flags); 21734303244SAndrey Konovalov return object; 21834303244SAndrey Konovalov } 21934303244SAndrey Konovalov 22034303244SAndrey Konovalov void * __must_check __kasan_kmalloc(struct kmem_cache *s, const void *object, 22134303244SAndrey Konovalov size_t size, gfp_t flags); 22234303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc(struct kmem_cache *s, 22334303244SAndrey Konovalov const void *object, size_t size, gfp_t flags) 22434303244SAndrey Konovalov { 22534303244SAndrey Konovalov if (kasan_enabled()) 22634303244SAndrey Konovalov return __kasan_kmalloc(s, object, size, flags); 22734303244SAndrey Konovalov return (void *)object; 22834303244SAndrey Konovalov } 22934303244SAndrey Konovalov 23034303244SAndrey Konovalov void * __must_check __kasan_kmalloc_large(const void *ptr, 23134303244SAndrey Konovalov size_t size, gfp_t flags); 23234303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc_large(const void *ptr, 23334303244SAndrey Konovalov size_t size, gfp_t flags) 23434303244SAndrey Konovalov { 23534303244SAndrey Konovalov if (kasan_enabled()) 23634303244SAndrey Konovalov return __kasan_kmalloc_large(ptr, size, flags); 23734303244SAndrey Konovalov return (void *)ptr; 23834303244SAndrey Konovalov } 23934303244SAndrey Konovalov 24034303244SAndrey Konovalov void * __must_check __kasan_krealloc(const void *object, 24134303244SAndrey Konovalov size_t new_size, gfp_t flags); 24234303244SAndrey Konovalov static __always_inline void * __must_check kasan_krealloc(const void *object, 24334303244SAndrey Konovalov size_t new_size, gfp_t flags) 24434303244SAndrey Konovalov { 24534303244SAndrey Konovalov if (kasan_enabled()) 24634303244SAndrey Konovalov return __kasan_krealloc(object, new_size, flags); 24734303244SAndrey Konovalov return (void *)object; 24834303244SAndrey Konovalov } 24934303244SAndrey Konovalov 25034303244SAndrey Konovalov void __kasan_kfree_large(void *ptr, unsigned long ip); 251027b37b5SAndrey Konovalov static __always_inline void kasan_kfree_large(void *ptr) 25234303244SAndrey Konovalov { 25334303244SAndrey Konovalov if (kasan_enabled()) 254027b37b5SAndrey Konovalov __kasan_kfree_large(ptr, _RET_IP_); 25534303244SAndrey Konovalov } 2569b75a867SAndrey Ryabinin 257611806b4SAndrey Konovalov /* 258611806b4SAndrey Konovalov * Unlike kasan_check_read/write(), kasan_check_byte() is performed even for 259611806b4SAndrey Konovalov * the hardware tag-based mode that doesn't rely on compiler instrumentation. 260611806b4SAndrey Konovalov */ 261611806b4SAndrey Konovalov bool __kasan_check_byte(const void *addr, unsigned long ip); 262611806b4SAndrey Konovalov static __always_inline bool kasan_check_byte(const void *addr) 263611806b4SAndrey Konovalov { 264611806b4SAndrey Konovalov if (kasan_enabled()) 265611806b4SAndrey Konovalov return __kasan_check_byte(addr, _RET_IP_); 266611806b4SAndrey Konovalov return true; 267611806b4SAndrey Konovalov } 268611806b4SAndrey Konovalov 269611806b4SAndrey Konovalov 270b0845ce5SMark Rutland bool kasan_save_enable_multi_shot(void); 271b0845ce5SMark Rutland void kasan_restore_multi_shot(bool enabled); 272b0845ce5SMark Rutland 2730b24beccSAndrey Ryabinin #else /* CONFIG_KASAN */ 2740b24beccSAndrey Ryabinin 27534303244SAndrey Konovalov static inline bool kasan_enabled(void) 27634303244SAndrey Konovalov { 27734303244SAndrey Konovalov return false; 27834303244SAndrey Konovalov } 279e86f8b09SAndrey Konovalov static inline slab_flags_t kasan_never_merge(void) 280e86f8b09SAndrey Konovalov { 281e86f8b09SAndrey Konovalov return 0; 282e86f8b09SAndrey Konovalov } 283cebd0eb2SAndrey Konovalov static inline void kasan_unpoison_range(const void *address, size_t size) {} 284b8c73fc2SAndrey Ryabinin static inline void kasan_alloc_pages(struct page *page, unsigned int order) {} 285b8c73fc2SAndrey Ryabinin static inline void kasan_free_pages(struct page *page, unsigned int order) {} 2867ed2f9e6SAlexander Potapenko static inline void kasan_cache_create(struct kmem_cache *cache, 287be4a7988SAlexey Dobriyan unsigned int *size, 288d50112edSAlexey Dobriyan slab_flags_t *flags) {} 289*92850134SAndrey Konovalov static inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) {} 29034303244SAndrey Konovalov static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; } 2910316bec2SAndrey Ryabinin static inline void kasan_poison_slab(struct page *page) {} 2920316bec2SAndrey Ryabinin static inline void kasan_unpoison_object_data(struct kmem_cache *cache, 2930316bec2SAndrey Ryabinin void *object) {} 2940316bec2SAndrey Ryabinin static inline void kasan_poison_object_data(struct kmem_cache *cache, 2950316bec2SAndrey Ryabinin void *object) {} 2960116523cSAndrey Konovalov static inline void *kasan_init_slab_obj(struct kmem_cache *cache, 2970116523cSAndrey Konovalov const void *object) 2980116523cSAndrey Konovalov { 2990116523cSAndrey Konovalov return (void *)object; 3000116523cSAndrey Konovalov } 301027b37b5SAndrey Konovalov static inline bool kasan_slab_free(struct kmem_cache *s, void *object) 3020116523cSAndrey Konovalov { 30334303244SAndrey Konovalov return false; 3040116523cSAndrey Konovalov } 305027b37b5SAndrey Konovalov static inline void kasan_slab_free_mempool(void *ptr) {} 30634303244SAndrey Konovalov static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object, 30734303244SAndrey Konovalov gfp_t flags) 30834303244SAndrey Konovalov { 30934303244SAndrey Konovalov return object; 31034303244SAndrey Konovalov } 3110116523cSAndrey Konovalov static inline void *kasan_kmalloc(struct kmem_cache *s, const void *object, 3120116523cSAndrey Konovalov size_t size, gfp_t flags) 3130116523cSAndrey Konovalov { 3140116523cSAndrey Konovalov return (void *)object; 3150116523cSAndrey Konovalov } 31634303244SAndrey Konovalov static inline void *kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags) 31734303244SAndrey Konovalov { 31834303244SAndrey Konovalov return (void *)ptr; 31934303244SAndrey Konovalov } 3200116523cSAndrey Konovalov static inline void *kasan_krealloc(const void *object, size_t new_size, 3210116523cSAndrey Konovalov gfp_t flags) 3220116523cSAndrey Konovalov { 3230116523cSAndrey Konovalov return (void *)object; 3240116523cSAndrey Konovalov } 325027b37b5SAndrey Konovalov static inline void kasan_kfree_large(void *ptr) {} 326611806b4SAndrey Konovalov static inline bool kasan_check_byte(const void *address) 327611806b4SAndrey Konovalov { 328611806b4SAndrey Konovalov return true; 329611806b4SAndrey Konovalov } 3309b75a867SAndrey Ryabinin 3310b24beccSAndrey Ryabinin #endif /* CONFIG_KASAN */ 3320b24beccSAndrey Ryabinin 333d56a9ef8SAndrey Konovalov #if defined(CONFIG_KASAN) && CONFIG_KASAN_STACK 334d56a9ef8SAndrey Konovalov void kasan_unpoison_task_stack(struct task_struct *task); 335d56a9ef8SAndrey Konovalov #else 336d56a9ef8SAndrey Konovalov static inline void kasan_unpoison_task_stack(struct task_struct *task) {} 337d56a9ef8SAndrey Konovalov #endif 338d56a9ef8SAndrey Konovalov 3392bd926b4SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC 3402bd926b4SAndrey Konovalov 3412bd926b4SAndrey Konovalov void kasan_cache_shrink(struct kmem_cache *cache); 3422bd926b4SAndrey Konovalov void kasan_cache_shutdown(struct kmem_cache *cache); 34326e760c9SWalter Wu void kasan_record_aux_stack(void *ptr); 3442bd926b4SAndrey Konovalov 3452bd926b4SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC */ 3462bd926b4SAndrey Konovalov 3472bd926b4SAndrey Konovalov static inline void kasan_cache_shrink(struct kmem_cache *cache) {} 3482bd926b4SAndrey Konovalov static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} 34926e760c9SWalter Wu static inline void kasan_record_aux_stack(void *ptr) {} 3502bd926b4SAndrey Konovalov 3512bd926b4SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */ 3522bd926b4SAndrey Konovalov 3532e903b91SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) 3543c9e3aa1SAndrey Konovalov 355c0054c56SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 356c0054c56SAndrey Konovalov { 357c0054c56SAndrey Konovalov return (void *)arch_kasan_reset_tag(addr); 358c0054c56SAndrey Konovalov } 3593c9e3aa1SAndrey Konovalov 36049c6631dSVincenzo Frascino /** 36149c6631dSVincenzo Frascino * kasan_report - print a report about a bad memory access detected by KASAN 36249c6631dSVincenzo Frascino * @addr: address of the bad access 36349c6631dSVincenzo Frascino * @size: size of the bad access 36449c6631dSVincenzo Frascino * @is_write: whether the bad access is a write or a read 36549c6631dSVincenzo Frascino * @ip: instruction pointer for the accessibility check or the bad access itself 36649c6631dSVincenzo Frascino */ 3678cceeff4SWalter Wu bool kasan_report(unsigned long addr, size_t size, 36841eea9cdSAndrey Konovalov bool is_write, unsigned long ip); 36941eea9cdSAndrey Konovalov 3702e903b91SAndrey Konovalov #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */ 3713c9e3aa1SAndrey Konovalov 3723c9e3aa1SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 3733c9e3aa1SAndrey Konovalov { 3743c9e3aa1SAndrey Konovalov return (void *)addr; 3753c9e3aa1SAndrey Konovalov } 3763c9e3aa1SAndrey Konovalov 3772e903b91SAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS*/ 3782e903b91SAndrey Konovalov 3792e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS 3802e903b91SAndrey Konovalov void __init kasan_init_sw_tags(void); 3812e903b91SAndrey Konovalov #else 3822e903b91SAndrey Konovalov static inline void kasan_init_sw_tags(void) { } 3832e903b91SAndrey Konovalov #endif 3842e903b91SAndrey Konovalov 3852e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 3862e903b91SAndrey Konovalov void kasan_init_hw_tags_cpu(void); 3872e903b91SAndrey Konovalov void __init kasan_init_hw_tags(void); 3882e903b91SAndrey Konovalov #else 3892e903b91SAndrey Konovalov static inline void kasan_init_hw_tags_cpu(void) { } 3902e903b91SAndrey Konovalov static inline void kasan_init_hw_tags(void) { } 3912e903b91SAndrey Konovalov #endif 392080eb83fSAndrey Konovalov 3933c5c3cfbSDaniel Axtens #ifdef CONFIG_KASAN_VMALLOC 3943b1a4a86SAndrey Konovalov 395d98c9e83SAndrey Ryabinin int kasan_populate_vmalloc(unsigned long addr, unsigned long size); 396d98c9e83SAndrey Ryabinin void kasan_poison_vmalloc(const void *start, unsigned long size); 397d98c9e83SAndrey Ryabinin void kasan_unpoison_vmalloc(const void *start, unsigned long size); 3983c5c3cfbSDaniel Axtens void kasan_release_vmalloc(unsigned long start, unsigned long end, 3993c5c3cfbSDaniel Axtens unsigned long free_region_start, 4003c5c3cfbSDaniel Axtens unsigned long free_region_end); 4013b1a4a86SAndrey Konovalov 4023b1a4a86SAndrey Konovalov #else /* CONFIG_KASAN_VMALLOC */ 4033b1a4a86SAndrey Konovalov 404d98c9e83SAndrey Ryabinin static inline int kasan_populate_vmalloc(unsigned long start, 405d98c9e83SAndrey Ryabinin unsigned long size) 4063c5c3cfbSDaniel Axtens { 4073c5c3cfbSDaniel Axtens return 0; 4083c5c3cfbSDaniel Axtens } 4093c5c3cfbSDaniel Axtens 410d98c9e83SAndrey Ryabinin static inline void kasan_poison_vmalloc(const void *start, unsigned long size) 411d98c9e83SAndrey Ryabinin { } 412d98c9e83SAndrey Ryabinin static inline void kasan_unpoison_vmalloc(const void *start, unsigned long size) 413d98c9e83SAndrey Ryabinin { } 4143c5c3cfbSDaniel Axtens static inline void kasan_release_vmalloc(unsigned long start, 4153c5c3cfbSDaniel Axtens unsigned long end, 4163c5c3cfbSDaniel Axtens unsigned long free_region_start, 4173c5c3cfbSDaniel Axtens unsigned long free_region_end) {} 4183b1a4a86SAndrey Konovalov 4193b1a4a86SAndrey Konovalov #endif /* CONFIG_KASAN_VMALLOC */ 4203b1a4a86SAndrey Konovalov 4210fea6e9aSAndrey Konovalov #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ 4220fea6e9aSAndrey Konovalov !defined(CONFIG_KASAN_VMALLOC) 4233b1a4a86SAndrey Konovalov 4243b1a4a86SAndrey Konovalov /* 4253b1a4a86SAndrey Konovalov * These functions provide a special case to support backing module 4263b1a4a86SAndrey Konovalov * allocations with real shadow memory. With KASAN vmalloc, the special 4273b1a4a86SAndrey Konovalov * case is unnecessary, as the work is handled in the generic case. 4283b1a4a86SAndrey Konovalov */ 4293b1a4a86SAndrey Konovalov int kasan_module_alloc(void *addr, size_t size); 4303b1a4a86SAndrey Konovalov void kasan_free_shadow(const struct vm_struct *vm); 4313b1a4a86SAndrey Konovalov 4320fea6e9aSAndrey Konovalov #else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4333b1a4a86SAndrey Konovalov 4343b1a4a86SAndrey Konovalov static inline int kasan_module_alloc(void *addr, size_t size) { return 0; } 4353b1a4a86SAndrey Konovalov static inline void kasan_free_shadow(const struct vm_struct *vm) {} 4363b1a4a86SAndrey Konovalov 4370fea6e9aSAndrey Konovalov #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4383c5c3cfbSDaniel Axtens 4392f004eeaSJann Horn #ifdef CONFIG_KASAN_INLINE 4402f004eeaSJann Horn void kasan_non_canonical_hook(unsigned long addr); 4412f004eeaSJann Horn #else /* CONFIG_KASAN_INLINE */ 4422f004eeaSJann Horn static inline void kasan_non_canonical_hook(unsigned long addr) { } 4432f004eeaSJann Horn #endif /* CONFIG_KASAN_INLINE */ 4442f004eeaSJann Horn 4450b24beccSAndrey Ryabinin #endif /* LINUX_KASAN_H */ 446