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 22d5750edfSAndrey Konovalov #endif 23d5750edfSAndrey Konovalov 2423689e91SAndrey Konovalov typedef unsigned int __bitwise kasan_vmalloc_flags_t; 2523689e91SAndrey Konovalov 26ec2a0f9cSAndrey Konovalov #define KASAN_VMALLOC_NONE ((__force kasan_vmalloc_flags_t)0x00u) 27ec2a0f9cSAndrey Konovalov #define KASAN_VMALLOC_INIT ((__force kasan_vmalloc_flags_t)0x01u) 28ec2a0f9cSAndrey Konovalov #define KASAN_VMALLOC_VM_ALLOC ((__force kasan_vmalloc_flags_t)0x02u) 29ec2a0f9cSAndrey Konovalov #define KASAN_VMALLOC_PROT_NORMAL ((__force kasan_vmalloc_flags_t)0x04u) 3023689e91SAndrey Konovalov 31d5750edfSAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) 32d5750edfSAndrey Konovalov 33d5750edfSAndrey Konovalov #include <linux/pgtable.h> 34d5750edfSAndrey Konovalov 35d5750edfSAndrey Konovalov /* Software KASAN implementations use shadow memory. */ 36d5750edfSAndrey Konovalov 37d5750edfSAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS 38a064cb00SAndrey Konovalov /* This matches KASAN_TAG_INVALID. */ 39a064cb00SAndrey Konovalov #define KASAN_SHADOW_INIT 0xFE 40d5750edfSAndrey Konovalov #else 41d5750edfSAndrey Konovalov #define KASAN_SHADOW_INIT 0 42d5750edfSAndrey Konovalov #endif 43d5750edfSAndrey Konovalov 4429970dc2SHailong Liu #ifndef PTE_HWTABLE_PTRS 4529970dc2SHailong Liu #define PTE_HWTABLE_PTRS 0 4629970dc2SHailong Liu #endif 4729970dc2SHailong Liu 489577dd74SAndrey Konovalov extern unsigned char kasan_early_shadow_page[PAGE_SIZE]; 49cb32c9c5SDaniel Axtens extern pte_t kasan_early_shadow_pte[MAX_PTRS_PER_PTE + PTE_HWTABLE_PTRS]; 50cb32c9c5SDaniel Axtens extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD]; 51cb32c9c5SDaniel Axtens extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD]; 529577dd74SAndrey Konovalov extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D]; 5369786cdbSAndrey Ryabinin 549577dd74SAndrey Konovalov int kasan_populate_early_shadow(const void *shadow_start, 5569786cdbSAndrey Ryabinin const void *shadow_end); 5669786cdbSAndrey Ryabinin 570b24beccSAndrey Ryabinin static inline void *kasan_mem_to_shadow(const void *addr) 580b24beccSAndrey Ryabinin { 590b24beccSAndrey Ryabinin return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) 600b24beccSAndrey Ryabinin + KASAN_SHADOW_OFFSET; 610b24beccSAndrey Ryabinin } 620b24beccSAndrey Ryabinin 63d5750edfSAndrey Konovalov int kasan_add_zero_shadow(void *start, unsigned long size); 64d5750edfSAndrey Konovalov void kasan_remove_zero_shadow(void *start, unsigned long size); 65d5750edfSAndrey Konovalov 66d73b4936SAndrey Konovalov /* Enable reporting bugs after kasan_disable_current() */ 67d73b4936SAndrey Konovalov extern void kasan_enable_current(void); 68d73b4936SAndrey Konovalov 69d73b4936SAndrey Konovalov /* Disable reporting bugs for current task */ 70d73b4936SAndrey Konovalov extern void kasan_disable_current(void); 71d73b4936SAndrey Konovalov 72d5750edfSAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 73d5750edfSAndrey Konovalov 74d5750edfSAndrey Konovalov static inline int kasan_add_zero_shadow(void *start, unsigned long size) 75d5750edfSAndrey Konovalov { 76d5750edfSAndrey Konovalov return 0; 77d5750edfSAndrey Konovalov } 78d5750edfSAndrey Konovalov static inline void kasan_remove_zero_shadow(void *start, 79d5750edfSAndrey Konovalov unsigned long size) 80d5750edfSAndrey Konovalov {} 81d5750edfSAndrey Konovalov 82d73b4936SAndrey Konovalov static inline void kasan_enable_current(void) {} 83d73b4936SAndrey Konovalov static inline void kasan_disable_current(void) {} 84d73b4936SAndrey Konovalov 85d5750edfSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 86d5750edfSAndrey Konovalov 8734303244SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 88e86f8b09SAndrey Konovalov 89e86f8b09SAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */ 90e86f8b09SAndrey Konovalov 91e86f8b09SAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */ 92e86f8b09SAndrey Konovalov 93e5af50a5SPeter Collingbourne static inline bool kasan_has_integrated_init(void) 94e5af50a5SPeter Collingbourne { 95e5af50a5SPeter Collingbourne return kasan_hw_tags_enabled(); 96e5af50a5SPeter Collingbourne } 97e5af50a5SPeter Collingbourne 987a3b8353SPeter Collingbourne #ifdef CONFIG_KASAN 997a3b8353SPeter Collingbourne 1007a3b8353SPeter Collingbourne struct kasan_cache { 1017a3b8353SPeter Collingbourne int alloc_meta_offset; 1027a3b8353SPeter Collingbourne int free_meta_offset; 1037a3b8353SPeter Collingbourne bool is_kmalloc; 1047a3b8353SPeter Collingbourne }; 1057a3b8353SPeter Collingbourne 106e86f8b09SAndrey Konovalov slab_flags_t __kasan_never_merge(void); 107e86f8b09SAndrey Konovalov static __always_inline slab_flags_t kasan_never_merge(void) 108e86f8b09SAndrey Konovalov { 109e86f8b09SAndrey Konovalov if (kasan_enabled()) 110e86f8b09SAndrey Konovalov return __kasan_never_merge(); 111e86f8b09SAndrey Konovalov return 0; 112e86f8b09SAndrey Konovalov } 11334303244SAndrey Konovalov 11434303244SAndrey Konovalov void __kasan_unpoison_range(const void *addr, size_t size); 11534303244SAndrey Konovalov static __always_inline void kasan_unpoison_range(const void *addr, size_t size) 11634303244SAndrey Konovalov { 11734303244SAndrey Konovalov if (kasan_enabled()) 11834303244SAndrey Konovalov __kasan_unpoison_range(addr, size); 11934303244SAndrey Konovalov } 12034303244SAndrey Konovalov 1217a3b8353SPeter Collingbourne void __kasan_poison_pages(struct page *page, unsigned int order, bool init); 1227a3b8353SPeter Collingbourne static __always_inline void kasan_poison_pages(struct page *page, 1231bb5eab3SAndrey Konovalov unsigned int order, bool init) 12434303244SAndrey Konovalov { 12534303244SAndrey Konovalov if (kasan_enabled()) 1267a3b8353SPeter Collingbourne __kasan_poison_pages(page, order, init); 12734303244SAndrey Konovalov } 12834303244SAndrey Konovalov 1297a3b8353SPeter Collingbourne void __kasan_unpoison_pages(struct page *page, unsigned int order, bool init); 1307a3b8353SPeter Collingbourne static __always_inline void kasan_unpoison_pages(struct page *page, 1311bb5eab3SAndrey Konovalov unsigned int order, bool init) 13234303244SAndrey Konovalov { 13334303244SAndrey Konovalov if (kasan_enabled()) 1347a3b8353SPeter Collingbourne __kasan_unpoison_pages(page, order, init); 13534303244SAndrey Konovalov } 13634303244SAndrey Konovalov 13734303244SAndrey Konovalov void __kasan_cache_create(struct kmem_cache *cache, unsigned int *size, 13834303244SAndrey Konovalov slab_flags_t *flags); 13934303244SAndrey Konovalov static __always_inline void kasan_cache_create(struct kmem_cache *cache, 14034303244SAndrey Konovalov unsigned int *size, slab_flags_t *flags) 14134303244SAndrey Konovalov { 14234303244SAndrey Konovalov if (kasan_enabled()) 14334303244SAndrey Konovalov __kasan_cache_create(cache, size, flags); 14434303244SAndrey Konovalov } 14534303244SAndrey Konovalov 14692850134SAndrey Konovalov void __kasan_cache_create_kmalloc(struct kmem_cache *cache); 14792850134SAndrey Konovalov static __always_inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) 14892850134SAndrey Konovalov { 14992850134SAndrey Konovalov if (kasan_enabled()) 15092850134SAndrey Konovalov __kasan_cache_create_kmalloc(cache); 15192850134SAndrey Konovalov } 15292850134SAndrey Konovalov 1536e48a966SMatthew Wilcox (Oracle) void __kasan_poison_slab(struct slab *slab); 1546e48a966SMatthew Wilcox (Oracle) static __always_inline void kasan_poison_slab(struct slab *slab) 15534303244SAndrey Konovalov { 15634303244SAndrey Konovalov if (kasan_enabled()) 1576e48a966SMatthew Wilcox (Oracle) __kasan_poison_slab(slab); 15834303244SAndrey Konovalov } 15934303244SAndrey Konovalov 16034303244SAndrey Konovalov void __kasan_unpoison_object_data(struct kmem_cache *cache, void *object); 16134303244SAndrey Konovalov static __always_inline void kasan_unpoison_object_data(struct kmem_cache *cache, 16234303244SAndrey Konovalov void *object) 16334303244SAndrey Konovalov { 16434303244SAndrey Konovalov if (kasan_enabled()) 16534303244SAndrey Konovalov __kasan_unpoison_object_data(cache, object); 16634303244SAndrey Konovalov } 16734303244SAndrey Konovalov 16834303244SAndrey Konovalov void __kasan_poison_object_data(struct kmem_cache *cache, void *object); 16934303244SAndrey Konovalov static __always_inline void kasan_poison_object_data(struct kmem_cache *cache, 17034303244SAndrey Konovalov void *object) 17134303244SAndrey Konovalov { 17234303244SAndrey Konovalov if (kasan_enabled()) 17334303244SAndrey Konovalov __kasan_poison_object_data(cache, object); 17434303244SAndrey Konovalov } 17534303244SAndrey Konovalov 17634303244SAndrey Konovalov void * __must_check __kasan_init_slab_obj(struct kmem_cache *cache, 17734303244SAndrey Konovalov const void *object); 17834303244SAndrey Konovalov static __always_inline void * __must_check kasan_init_slab_obj( 17934303244SAndrey Konovalov struct kmem_cache *cache, const void *object) 18034303244SAndrey Konovalov { 18134303244SAndrey Konovalov if (kasan_enabled()) 18234303244SAndrey Konovalov return __kasan_init_slab_obj(cache, object); 18334303244SAndrey Konovalov return (void *)object; 18434303244SAndrey Konovalov } 18534303244SAndrey Konovalov 186d57a964eSAndrey Konovalov bool __kasan_slab_free(struct kmem_cache *s, void *object, 187d57a964eSAndrey Konovalov unsigned long ip, bool init); 188d57a964eSAndrey Konovalov static __always_inline bool kasan_slab_free(struct kmem_cache *s, 189d57a964eSAndrey Konovalov void *object, bool init) 19034303244SAndrey Konovalov { 19134303244SAndrey Konovalov if (kasan_enabled()) 192d57a964eSAndrey Konovalov return __kasan_slab_free(s, object, _RET_IP_, init); 19334303244SAndrey Konovalov return false; 19434303244SAndrey Konovalov } 19534303244SAndrey Konovalov 196200072ceSAndrey Konovalov void __kasan_kfree_large(void *ptr, unsigned long ip); 197200072ceSAndrey Konovalov static __always_inline void kasan_kfree_large(void *ptr) 198200072ceSAndrey Konovalov { 199200072ceSAndrey Konovalov if (kasan_enabled()) 200200072ceSAndrey Konovalov __kasan_kfree_large(ptr, _RET_IP_); 201200072ceSAndrey Konovalov } 202200072ceSAndrey 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, 211da844b78SAndrey Konovalov void *object, gfp_t flags, bool init); 21234303244SAndrey Konovalov static __always_inline void * __must_check kasan_slab_alloc( 213da844b78SAndrey Konovalov struct kmem_cache *s, void *object, gfp_t flags, bool init) 21434303244SAndrey Konovalov { 21534303244SAndrey Konovalov if (kasan_enabled()) 216da844b78SAndrey Konovalov return __kasan_slab_alloc(s, object, flags, init); 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 250611806b4SAndrey Konovalov /* 251611806b4SAndrey Konovalov * Unlike kasan_check_read/write(), kasan_check_byte() is performed even for 252611806b4SAndrey Konovalov * the hardware tag-based mode that doesn't rely on compiler instrumentation. 253611806b4SAndrey Konovalov */ 254611806b4SAndrey Konovalov bool __kasan_check_byte(const void *addr, unsigned long ip); 255611806b4SAndrey Konovalov static __always_inline bool kasan_check_byte(const void *addr) 256611806b4SAndrey Konovalov { 257611806b4SAndrey Konovalov if (kasan_enabled()) 258611806b4SAndrey Konovalov return __kasan_check_byte(addr, _RET_IP_); 259611806b4SAndrey Konovalov return true; 260611806b4SAndrey Konovalov } 261611806b4SAndrey Konovalov 2620b24beccSAndrey Ryabinin #else /* CONFIG_KASAN */ 2630b24beccSAndrey Ryabinin 264e86f8b09SAndrey Konovalov static inline slab_flags_t kasan_never_merge(void) 265e86f8b09SAndrey Konovalov { 266e86f8b09SAndrey Konovalov return 0; 267e86f8b09SAndrey Konovalov } 268cebd0eb2SAndrey Konovalov static inline void kasan_unpoison_range(const void *address, size_t size) {} 2697a3b8353SPeter Collingbourne static inline void kasan_poison_pages(struct page *page, unsigned int order, 2707a3b8353SPeter Collingbourne bool init) {} 2717a3b8353SPeter Collingbourne static inline void kasan_unpoison_pages(struct page *page, unsigned int order, 2727a3b8353SPeter Collingbourne bool init) {} 2737ed2f9e6SAlexander Potapenko static inline void kasan_cache_create(struct kmem_cache *cache, 274be4a7988SAlexey Dobriyan unsigned int *size, 275d50112edSAlexey Dobriyan slab_flags_t *flags) {} 27692850134SAndrey Konovalov static inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) {} 2776e48a966SMatthew Wilcox (Oracle) static inline void kasan_poison_slab(struct slab *slab) {} 2780316bec2SAndrey Ryabinin static inline void kasan_unpoison_object_data(struct kmem_cache *cache, 2790316bec2SAndrey Ryabinin void *object) {} 2800316bec2SAndrey Ryabinin static inline void kasan_poison_object_data(struct kmem_cache *cache, 2810316bec2SAndrey Ryabinin void *object) {} 2820116523cSAndrey Konovalov static inline void *kasan_init_slab_obj(struct kmem_cache *cache, 2830116523cSAndrey Konovalov const void *object) 2840116523cSAndrey Konovalov { 2850116523cSAndrey Konovalov return (void *)object; 2860116523cSAndrey Konovalov } 287d57a964eSAndrey Konovalov static inline bool kasan_slab_free(struct kmem_cache *s, void *object, bool init) 2880116523cSAndrey Konovalov { 28934303244SAndrey Konovalov return false; 2900116523cSAndrey Konovalov } 291200072ceSAndrey Konovalov static inline void kasan_kfree_large(void *ptr) {} 292027b37b5SAndrey Konovalov static inline void kasan_slab_free_mempool(void *ptr) {} 29334303244SAndrey Konovalov static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object, 294da844b78SAndrey Konovalov gfp_t flags, bool init) 29534303244SAndrey Konovalov { 29634303244SAndrey Konovalov return object; 29734303244SAndrey Konovalov } 2980116523cSAndrey Konovalov static inline void *kasan_kmalloc(struct kmem_cache *s, const void *object, 2990116523cSAndrey Konovalov size_t size, gfp_t flags) 3000116523cSAndrey Konovalov { 3010116523cSAndrey Konovalov return (void *)object; 3020116523cSAndrey Konovalov } 30334303244SAndrey Konovalov static inline void *kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags) 30434303244SAndrey Konovalov { 30534303244SAndrey Konovalov return (void *)ptr; 30634303244SAndrey Konovalov } 3070116523cSAndrey Konovalov static inline void *kasan_krealloc(const void *object, size_t new_size, 3080116523cSAndrey Konovalov gfp_t flags) 3090116523cSAndrey Konovalov { 3100116523cSAndrey Konovalov return (void *)object; 3110116523cSAndrey Konovalov } 312611806b4SAndrey Konovalov static inline bool kasan_check_byte(const void *address) 313611806b4SAndrey Konovalov { 314611806b4SAndrey Konovalov return true; 315611806b4SAndrey Konovalov } 3169b75a867SAndrey Ryabinin 3170b24beccSAndrey Ryabinin #endif /* CONFIG_KASAN */ 3180b24beccSAndrey Ryabinin 31902c58773SWalter Wu #if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK) 320d56a9ef8SAndrey Konovalov void kasan_unpoison_task_stack(struct task_struct *task); 321d56a9ef8SAndrey Konovalov #else 322d56a9ef8SAndrey Konovalov static inline void kasan_unpoison_task_stack(struct task_struct *task) {} 323d56a9ef8SAndrey Konovalov #endif 324d56a9ef8SAndrey Konovalov 3252bd926b4SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC 3262bd926b4SAndrey Konovalov 327*f372bde9SAndrey Konovalov size_t kasan_metadata_size(struct kmem_cache *cache); 328*f372bde9SAndrey Konovalov 3292bd926b4SAndrey Konovalov void kasan_cache_shrink(struct kmem_cache *cache); 3302bd926b4SAndrey Konovalov void kasan_cache_shutdown(struct kmem_cache *cache); 33126e760c9SWalter Wu void kasan_record_aux_stack(void *ptr); 3327cb3007cSMarco Elver void kasan_record_aux_stack_noalloc(void *ptr); 3332bd926b4SAndrey Konovalov 3342bd926b4SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC */ 3352bd926b4SAndrey Konovalov 336*f372bde9SAndrey Konovalov /* Tag-based KASAN modes do not use per-object metadata. */ 337*f372bde9SAndrey Konovalov static inline size_t kasan_metadata_size(struct kmem_cache *cache) 338*f372bde9SAndrey Konovalov { 339*f372bde9SAndrey Konovalov return 0; 340*f372bde9SAndrey Konovalov } 341*f372bde9SAndrey Konovalov 3422bd926b4SAndrey Konovalov static inline void kasan_cache_shrink(struct kmem_cache *cache) {} 3432bd926b4SAndrey Konovalov static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} 34426e760c9SWalter Wu static inline void kasan_record_aux_stack(void *ptr) {} 3457cb3007cSMarco Elver static inline void kasan_record_aux_stack_noalloc(void *ptr) {} 3462bd926b4SAndrey Konovalov 3472bd926b4SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */ 3482bd926b4SAndrey Konovalov 3492e903b91SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) 3503c9e3aa1SAndrey Konovalov 351c0054c56SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 352c0054c56SAndrey Konovalov { 353c0054c56SAndrey Konovalov return (void *)arch_kasan_reset_tag(addr); 354c0054c56SAndrey Konovalov } 3553c9e3aa1SAndrey Konovalov 35649c6631dSVincenzo Frascino /** 35749c6631dSVincenzo Frascino * kasan_report - print a report about a bad memory access detected by KASAN 35849c6631dSVincenzo Frascino * @addr: address of the bad access 35949c6631dSVincenzo Frascino * @size: size of the bad access 36049c6631dSVincenzo Frascino * @is_write: whether the bad access is a write or a read 36149c6631dSVincenzo Frascino * @ip: instruction pointer for the accessibility check or the bad access itself 36249c6631dSVincenzo Frascino */ 3638cceeff4SWalter Wu bool kasan_report(unsigned long addr, size_t size, 36441eea9cdSAndrey Konovalov bool is_write, unsigned long ip); 36541eea9cdSAndrey Konovalov 3662e903b91SAndrey Konovalov #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */ 3673c9e3aa1SAndrey Konovalov 3683c9e3aa1SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 3693c9e3aa1SAndrey Konovalov { 3703c9e3aa1SAndrey Konovalov return (void *)addr; 3713c9e3aa1SAndrey Konovalov } 3723c9e3aa1SAndrey Konovalov 3732e903b91SAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS*/ 3742e903b91SAndrey Konovalov 3758f7b5054SVincenzo Frascino #ifdef CONFIG_KASAN_HW_TAGS 3768f7b5054SVincenzo Frascino 3778f7b5054SVincenzo Frascino void kasan_report_async(void); 3788f7b5054SVincenzo Frascino 3798f7b5054SVincenzo Frascino #endif /* CONFIG_KASAN_HW_TAGS */ 3808f7b5054SVincenzo Frascino 3812e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS 3822e903b91SAndrey Konovalov void __init kasan_init_sw_tags(void); 3832e903b91SAndrey Konovalov #else 3842e903b91SAndrey Konovalov static inline void kasan_init_sw_tags(void) { } 3852e903b91SAndrey Konovalov #endif 3862e903b91SAndrey Konovalov 3872e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 3882e903b91SAndrey Konovalov void kasan_init_hw_tags_cpu(void); 3892e903b91SAndrey Konovalov void __init kasan_init_hw_tags(void); 3902e903b91SAndrey Konovalov #else 3912e903b91SAndrey Konovalov static inline void kasan_init_hw_tags_cpu(void) { } 3922e903b91SAndrey Konovalov static inline void kasan_init_hw_tags(void) { } 3932e903b91SAndrey Konovalov #endif 394080eb83fSAndrey Konovalov 3953c5c3cfbSDaniel Axtens #ifdef CONFIG_KASAN_VMALLOC 3963b1a4a86SAndrey Konovalov 39723689e91SAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) 39823689e91SAndrey Konovalov 3995bd9bae2SAndrey Konovalov void kasan_populate_early_vm_area_shadow(void *start, unsigned long size); 400d98c9e83SAndrey Ryabinin int kasan_populate_vmalloc(unsigned long addr, unsigned long size); 4013c5c3cfbSDaniel Axtens void kasan_release_vmalloc(unsigned long start, unsigned long end, 4023c5c3cfbSDaniel Axtens unsigned long free_region_start, 4033c5c3cfbSDaniel Axtens unsigned long free_region_end); 4043b1a4a86SAndrey Konovalov 40523689e91SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 40623689e91SAndrey Konovalov 40723689e91SAndrey Konovalov static inline void kasan_populate_early_vm_area_shadow(void *start, 40823689e91SAndrey Konovalov unsigned long size) 40923689e91SAndrey Konovalov { } 41023689e91SAndrey Konovalov static inline int kasan_populate_vmalloc(unsigned long start, 411579fb0acSAndrey Konovalov unsigned long size) 412579fb0acSAndrey Konovalov { 41323689e91SAndrey Konovalov return 0; 41423689e91SAndrey Konovalov } 41523689e91SAndrey Konovalov static inline void kasan_release_vmalloc(unsigned long start, 41623689e91SAndrey Konovalov unsigned long end, 41723689e91SAndrey Konovalov unsigned long free_region_start, 41823689e91SAndrey Konovalov unsigned long free_region_end) { } 41923689e91SAndrey Konovalov 42023689e91SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 42123689e91SAndrey Konovalov 42223689e91SAndrey Konovalov void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, 42323689e91SAndrey Konovalov kasan_vmalloc_flags_t flags); 42423689e91SAndrey Konovalov static __always_inline void *kasan_unpoison_vmalloc(const void *start, 42523689e91SAndrey Konovalov unsigned long size, 42623689e91SAndrey Konovalov kasan_vmalloc_flags_t flags) 42723689e91SAndrey Konovalov { 428579fb0acSAndrey Konovalov if (kasan_enabled()) 42923689e91SAndrey Konovalov return __kasan_unpoison_vmalloc(start, size, flags); 4301d96320fSAndrey Konovalov return (void *)start; 431579fb0acSAndrey Konovalov } 432579fb0acSAndrey Konovalov 433579fb0acSAndrey Konovalov void __kasan_poison_vmalloc(const void *start, unsigned long size); 434579fb0acSAndrey Konovalov static __always_inline void kasan_poison_vmalloc(const void *start, 435579fb0acSAndrey Konovalov unsigned long size) 436579fb0acSAndrey Konovalov { 437579fb0acSAndrey Konovalov if (kasan_enabled()) 438579fb0acSAndrey Konovalov __kasan_poison_vmalloc(start, size); 439579fb0acSAndrey Konovalov } 4403252b1d8SKefeng Wang 4413b1a4a86SAndrey Konovalov #else /* CONFIG_KASAN_VMALLOC */ 4423b1a4a86SAndrey Konovalov 4435bd9bae2SAndrey Konovalov static inline void kasan_populate_early_vm_area_shadow(void *start, 4445bd9bae2SAndrey Konovalov unsigned long size) { } 445d98c9e83SAndrey Ryabinin static inline int kasan_populate_vmalloc(unsigned long start, 446d98c9e83SAndrey Ryabinin unsigned long size) 4473c5c3cfbSDaniel Axtens { 4483c5c3cfbSDaniel Axtens return 0; 4493c5c3cfbSDaniel Axtens } 4503c5c3cfbSDaniel Axtens static inline void kasan_release_vmalloc(unsigned long start, 4513c5c3cfbSDaniel Axtens unsigned long end, 4523c5c3cfbSDaniel Axtens unsigned long free_region_start, 4533c5c3cfbSDaniel Axtens unsigned long free_region_end) { } 4543b1a4a86SAndrey Konovalov 4551d96320fSAndrey Konovalov static inline void *kasan_unpoison_vmalloc(const void *start, 45623689e91SAndrey Konovalov unsigned long size, 45723689e91SAndrey Konovalov kasan_vmalloc_flags_t flags) 4581d96320fSAndrey Konovalov { 4591d96320fSAndrey Konovalov return (void *)start; 4601d96320fSAndrey Konovalov } 4615bd9bae2SAndrey Konovalov static inline void kasan_poison_vmalloc(const void *start, unsigned long size) 4623252b1d8SKefeng Wang { } 4633252b1d8SKefeng Wang 4643b1a4a86SAndrey Konovalov #endif /* CONFIG_KASAN_VMALLOC */ 4653b1a4a86SAndrey Konovalov 4660fea6e9aSAndrey Konovalov #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ 4670fea6e9aSAndrey Konovalov !defined(CONFIG_KASAN_VMALLOC) 4683b1a4a86SAndrey Konovalov 4693b1a4a86SAndrey Konovalov /* 47063840de2SAndrey Konovalov * These functions allocate and free shadow memory for kernel modules. 47163840de2SAndrey Konovalov * They are only required when KASAN_VMALLOC is not supported, as otherwise 47263840de2SAndrey Konovalov * shadow memory is allocated by the generic vmalloc handlers. 4733b1a4a86SAndrey Konovalov */ 47463840de2SAndrey Konovalov int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask); 47563840de2SAndrey Konovalov void kasan_free_module_shadow(const struct vm_struct *vm); 4763b1a4a86SAndrey Konovalov 4770fea6e9aSAndrey Konovalov #else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4783b1a4a86SAndrey Konovalov 47963840de2SAndrey Konovalov static inline int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask) { return 0; } 48063840de2SAndrey Konovalov static inline void kasan_free_module_shadow(const struct vm_struct *vm) {} 4813b1a4a86SAndrey Konovalov 4820fea6e9aSAndrey Konovalov #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4833c5c3cfbSDaniel Axtens 4842f004eeaSJann Horn #ifdef CONFIG_KASAN_INLINE 4852f004eeaSJann Horn void kasan_non_canonical_hook(unsigned long addr); 4862f004eeaSJann Horn #else /* CONFIG_KASAN_INLINE */ 4872f004eeaSJann Horn static inline void kasan_non_canonical_hook(unsigned long addr) { } 4882f004eeaSJann Horn #endif /* CONFIG_KASAN_INLINE */ 4892f004eeaSJann Horn 4900b24beccSAndrey Ryabinin #endif /* LINUX_KASAN_H */ 491