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 57*9b04c764SQing Zhang #ifndef __HAVE_ARCH_SHADOW_MAP 580b24beccSAndrey Ryabinin static inline void *kasan_mem_to_shadow(const void *addr) 590b24beccSAndrey Ryabinin { 600b24beccSAndrey Ryabinin return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) 610b24beccSAndrey Ryabinin + KASAN_SHADOW_OFFSET; 620b24beccSAndrey Ryabinin } 63*9b04c764SQing Zhang #endif 640b24beccSAndrey Ryabinin 65d5750edfSAndrey Konovalov int kasan_add_zero_shadow(void *start, unsigned long size); 66d5750edfSAndrey Konovalov void kasan_remove_zero_shadow(void *start, unsigned long size); 67d5750edfSAndrey Konovalov 68d73b4936SAndrey Konovalov /* Enable reporting bugs after kasan_disable_current() */ 69d73b4936SAndrey Konovalov extern void kasan_enable_current(void); 70d73b4936SAndrey Konovalov 71d73b4936SAndrey Konovalov /* Disable reporting bugs for current task */ 72d73b4936SAndrey Konovalov extern void kasan_disable_current(void); 73d73b4936SAndrey Konovalov 74d5750edfSAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 75d5750edfSAndrey Konovalov 76d5750edfSAndrey Konovalov static inline int kasan_add_zero_shadow(void *start, unsigned long size) 77d5750edfSAndrey Konovalov { 78d5750edfSAndrey Konovalov return 0; 79d5750edfSAndrey Konovalov } 80d5750edfSAndrey Konovalov static inline void kasan_remove_zero_shadow(void *start, 81d5750edfSAndrey Konovalov unsigned long size) 82d5750edfSAndrey Konovalov {} 83d5750edfSAndrey Konovalov 84d73b4936SAndrey Konovalov static inline void kasan_enable_current(void) {} 85d73b4936SAndrey Konovalov static inline void kasan_disable_current(void) {} 86d73b4936SAndrey Konovalov 87d5750edfSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 88d5750edfSAndrey Konovalov 8934303244SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 90e86f8b09SAndrey Konovalov 91e86f8b09SAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */ 92e86f8b09SAndrey Konovalov 93e86f8b09SAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */ 94e86f8b09SAndrey Konovalov 95e5af50a5SPeter Collingbourne static inline bool kasan_has_integrated_init(void) 96e5af50a5SPeter Collingbourne { 97e5af50a5SPeter Collingbourne return kasan_hw_tags_enabled(); 98e5af50a5SPeter Collingbourne } 99e5af50a5SPeter Collingbourne 1007a3b8353SPeter Collingbourne #ifdef CONFIG_KASAN 10134303244SAndrey Konovalov void __kasan_unpoison_range(const void *addr, size_t size); 10234303244SAndrey Konovalov static __always_inline void kasan_unpoison_range(const void *addr, size_t size) 10334303244SAndrey Konovalov { 10434303244SAndrey Konovalov if (kasan_enabled()) 10534303244SAndrey Konovalov __kasan_unpoison_range(addr, size); 10634303244SAndrey Konovalov } 10734303244SAndrey Konovalov 1087a3b8353SPeter Collingbourne void __kasan_poison_pages(struct page *page, unsigned int order, bool init); 1097a3b8353SPeter Collingbourne static __always_inline void kasan_poison_pages(struct page *page, 1101bb5eab3SAndrey Konovalov unsigned int order, bool init) 11134303244SAndrey Konovalov { 11234303244SAndrey Konovalov if (kasan_enabled()) 1137a3b8353SPeter Collingbourne __kasan_poison_pages(page, order, init); 11434303244SAndrey Konovalov } 11534303244SAndrey Konovalov 11644383cefSAndrey Konovalov bool __kasan_unpoison_pages(struct page *page, unsigned int order, bool init); 11744383cefSAndrey Konovalov static __always_inline bool kasan_unpoison_pages(struct page *page, 1181bb5eab3SAndrey Konovalov unsigned int order, bool init) 11934303244SAndrey Konovalov { 12034303244SAndrey Konovalov if (kasan_enabled()) 12144383cefSAndrey Konovalov return __kasan_unpoison_pages(page, order, init); 12244383cefSAndrey Konovalov return false; 12334303244SAndrey Konovalov } 12434303244SAndrey Konovalov 1256e48a966SMatthew Wilcox (Oracle) void __kasan_poison_slab(struct slab *slab); 1266e48a966SMatthew Wilcox (Oracle) static __always_inline void kasan_poison_slab(struct slab *slab) 12734303244SAndrey Konovalov { 12834303244SAndrey Konovalov if (kasan_enabled()) 1296e48a966SMatthew Wilcox (Oracle) __kasan_poison_slab(slab); 13034303244SAndrey Konovalov } 13134303244SAndrey Konovalov 13234303244SAndrey Konovalov void __kasan_unpoison_object_data(struct kmem_cache *cache, void *object); 13334303244SAndrey Konovalov static __always_inline void kasan_unpoison_object_data(struct kmem_cache *cache, 13434303244SAndrey Konovalov void *object) 13534303244SAndrey Konovalov { 13634303244SAndrey Konovalov if (kasan_enabled()) 13734303244SAndrey Konovalov __kasan_unpoison_object_data(cache, object); 13834303244SAndrey Konovalov } 13934303244SAndrey Konovalov 14034303244SAndrey Konovalov void __kasan_poison_object_data(struct kmem_cache *cache, void *object); 14134303244SAndrey Konovalov static __always_inline void kasan_poison_object_data(struct kmem_cache *cache, 14234303244SAndrey Konovalov void *object) 14334303244SAndrey Konovalov { 14434303244SAndrey Konovalov if (kasan_enabled()) 14534303244SAndrey Konovalov __kasan_poison_object_data(cache, object); 14634303244SAndrey Konovalov } 14734303244SAndrey Konovalov 14834303244SAndrey Konovalov void * __must_check __kasan_init_slab_obj(struct kmem_cache *cache, 14934303244SAndrey Konovalov const void *object); 15034303244SAndrey Konovalov static __always_inline void * __must_check kasan_init_slab_obj( 15134303244SAndrey Konovalov struct kmem_cache *cache, const void *object) 15234303244SAndrey Konovalov { 15334303244SAndrey Konovalov if (kasan_enabled()) 15434303244SAndrey Konovalov return __kasan_init_slab_obj(cache, object); 15534303244SAndrey Konovalov return (void *)object; 15634303244SAndrey Konovalov } 15734303244SAndrey Konovalov 158d57a964eSAndrey Konovalov bool __kasan_slab_free(struct kmem_cache *s, void *object, 159d57a964eSAndrey Konovalov unsigned long ip, bool init); 160d57a964eSAndrey Konovalov static __always_inline bool kasan_slab_free(struct kmem_cache *s, 161d57a964eSAndrey Konovalov void *object, bool init) 16234303244SAndrey Konovalov { 16334303244SAndrey Konovalov if (kasan_enabled()) 164d57a964eSAndrey Konovalov return __kasan_slab_free(s, object, _RET_IP_, init); 16534303244SAndrey Konovalov return false; 16634303244SAndrey Konovalov } 16734303244SAndrey Konovalov 168200072ceSAndrey Konovalov void __kasan_kfree_large(void *ptr, unsigned long ip); 169200072ceSAndrey Konovalov static __always_inline void kasan_kfree_large(void *ptr) 170200072ceSAndrey Konovalov { 171200072ceSAndrey Konovalov if (kasan_enabled()) 172200072ceSAndrey Konovalov __kasan_kfree_large(ptr, _RET_IP_); 173200072ceSAndrey Konovalov } 174200072ceSAndrey Konovalov 175eeb3160cSAndrey Konovalov void __kasan_slab_free_mempool(void *ptr, unsigned long ip); 176027b37b5SAndrey Konovalov static __always_inline void kasan_slab_free_mempool(void *ptr) 177eeb3160cSAndrey Konovalov { 178eeb3160cSAndrey Konovalov if (kasan_enabled()) 179027b37b5SAndrey Konovalov __kasan_slab_free_mempool(ptr, _RET_IP_); 180eeb3160cSAndrey Konovalov } 181eeb3160cSAndrey Konovalov 18234303244SAndrey Konovalov void * __must_check __kasan_slab_alloc(struct kmem_cache *s, 183da844b78SAndrey Konovalov void *object, gfp_t flags, bool init); 18434303244SAndrey Konovalov static __always_inline void * __must_check kasan_slab_alloc( 185da844b78SAndrey Konovalov struct kmem_cache *s, void *object, gfp_t flags, bool init) 18634303244SAndrey Konovalov { 18734303244SAndrey Konovalov if (kasan_enabled()) 188da844b78SAndrey Konovalov return __kasan_slab_alloc(s, object, flags, init); 18934303244SAndrey Konovalov return object; 19034303244SAndrey Konovalov } 19134303244SAndrey Konovalov 19234303244SAndrey Konovalov void * __must_check __kasan_kmalloc(struct kmem_cache *s, const void *object, 19334303244SAndrey Konovalov size_t size, gfp_t flags); 19434303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc(struct kmem_cache *s, 19534303244SAndrey Konovalov const void *object, size_t size, gfp_t flags) 19634303244SAndrey Konovalov { 19734303244SAndrey Konovalov if (kasan_enabled()) 19834303244SAndrey Konovalov return __kasan_kmalloc(s, object, size, flags); 19934303244SAndrey Konovalov return (void *)object; 20034303244SAndrey Konovalov } 20134303244SAndrey Konovalov 20234303244SAndrey Konovalov void * __must_check __kasan_kmalloc_large(const void *ptr, 20334303244SAndrey Konovalov size_t size, gfp_t flags); 20434303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc_large(const void *ptr, 20534303244SAndrey Konovalov size_t size, gfp_t flags) 20634303244SAndrey Konovalov { 20734303244SAndrey Konovalov if (kasan_enabled()) 20834303244SAndrey Konovalov return __kasan_kmalloc_large(ptr, size, flags); 20934303244SAndrey Konovalov return (void *)ptr; 21034303244SAndrey Konovalov } 21134303244SAndrey Konovalov 21234303244SAndrey Konovalov void * __must_check __kasan_krealloc(const void *object, 21334303244SAndrey Konovalov size_t new_size, gfp_t flags); 21434303244SAndrey Konovalov static __always_inline void * __must_check kasan_krealloc(const void *object, 21534303244SAndrey Konovalov size_t new_size, gfp_t flags) 21634303244SAndrey Konovalov { 21734303244SAndrey Konovalov if (kasan_enabled()) 21834303244SAndrey Konovalov return __kasan_krealloc(object, new_size, flags); 21934303244SAndrey Konovalov return (void *)object; 22034303244SAndrey Konovalov } 22134303244SAndrey Konovalov 222611806b4SAndrey Konovalov /* 223611806b4SAndrey Konovalov * Unlike kasan_check_read/write(), kasan_check_byte() is performed even for 224611806b4SAndrey Konovalov * the hardware tag-based mode that doesn't rely on compiler instrumentation. 225611806b4SAndrey Konovalov */ 226611806b4SAndrey Konovalov bool __kasan_check_byte(const void *addr, unsigned long ip); 227611806b4SAndrey Konovalov static __always_inline bool kasan_check_byte(const void *addr) 228611806b4SAndrey Konovalov { 229611806b4SAndrey Konovalov if (kasan_enabled()) 230611806b4SAndrey Konovalov return __kasan_check_byte(addr, _RET_IP_); 231611806b4SAndrey Konovalov return true; 232611806b4SAndrey Konovalov } 233611806b4SAndrey Konovalov 2340b24beccSAndrey Ryabinin #else /* CONFIG_KASAN */ 2350b24beccSAndrey Ryabinin 236cebd0eb2SAndrey Konovalov static inline void kasan_unpoison_range(const void *address, size_t size) {} 2377a3b8353SPeter Collingbourne static inline void kasan_poison_pages(struct page *page, unsigned int order, 2387a3b8353SPeter Collingbourne bool init) {} 23944383cefSAndrey Konovalov static inline bool kasan_unpoison_pages(struct page *page, unsigned int order, 24044383cefSAndrey Konovalov bool init) 24144383cefSAndrey Konovalov { 24244383cefSAndrey Konovalov return false; 24344383cefSAndrey Konovalov } 2446e48a966SMatthew Wilcox (Oracle) static inline void kasan_poison_slab(struct slab *slab) {} 2450316bec2SAndrey Ryabinin static inline void kasan_unpoison_object_data(struct kmem_cache *cache, 2460316bec2SAndrey Ryabinin void *object) {} 2470316bec2SAndrey Ryabinin static inline void kasan_poison_object_data(struct kmem_cache *cache, 2480316bec2SAndrey Ryabinin void *object) {} 2490116523cSAndrey Konovalov static inline void *kasan_init_slab_obj(struct kmem_cache *cache, 2500116523cSAndrey Konovalov const void *object) 2510116523cSAndrey Konovalov { 2520116523cSAndrey Konovalov return (void *)object; 2530116523cSAndrey Konovalov } 254d57a964eSAndrey Konovalov static inline bool kasan_slab_free(struct kmem_cache *s, void *object, bool init) 2550116523cSAndrey Konovalov { 25634303244SAndrey Konovalov return false; 2570116523cSAndrey Konovalov } 258200072ceSAndrey Konovalov static inline void kasan_kfree_large(void *ptr) {} 259027b37b5SAndrey Konovalov static inline void kasan_slab_free_mempool(void *ptr) {} 26034303244SAndrey Konovalov static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object, 261da844b78SAndrey Konovalov gfp_t flags, bool init) 26234303244SAndrey Konovalov { 26334303244SAndrey Konovalov return object; 26434303244SAndrey Konovalov } 2650116523cSAndrey Konovalov static inline void *kasan_kmalloc(struct kmem_cache *s, const void *object, 2660116523cSAndrey Konovalov size_t size, gfp_t flags) 2670116523cSAndrey Konovalov { 2680116523cSAndrey Konovalov return (void *)object; 2690116523cSAndrey Konovalov } 27034303244SAndrey Konovalov static inline void *kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags) 27134303244SAndrey Konovalov { 27234303244SAndrey Konovalov return (void *)ptr; 27334303244SAndrey Konovalov } 2740116523cSAndrey Konovalov static inline void *kasan_krealloc(const void *object, size_t new_size, 2750116523cSAndrey Konovalov gfp_t flags) 2760116523cSAndrey Konovalov { 2770116523cSAndrey Konovalov return (void *)object; 2780116523cSAndrey Konovalov } 279611806b4SAndrey Konovalov static inline bool kasan_check_byte(const void *address) 280611806b4SAndrey Konovalov { 281611806b4SAndrey Konovalov return true; 282611806b4SAndrey Konovalov } 2839b75a867SAndrey Ryabinin 2840b24beccSAndrey Ryabinin #endif /* CONFIG_KASAN */ 2850b24beccSAndrey Ryabinin 28602c58773SWalter Wu #if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK) 287d56a9ef8SAndrey Konovalov void kasan_unpoison_task_stack(struct task_struct *task); 288d56a9ef8SAndrey Konovalov #else 289d56a9ef8SAndrey Konovalov static inline void kasan_unpoison_task_stack(struct task_struct *task) {} 290d56a9ef8SAndrey Konovalov #endif 291d56a9ef8SAndrey Konovalov 2922bd926b4SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC 2932bd926b4SAndrey Konovalov 294bbc61844SFeng Tang struct kasan_cache { 295bbc61844SFeng Tang int alloc_meta_offset; 296bbc61844SFeng Tang int free_meta_offset; 297bbc61844SFeng Tang }; 298bbc61844SFeng Tang 2995d1ba310SFeng Tang size_t kasan_metadata_size(struct kmem_cache *cache, bool in_object); 3003b7f8813SAndrey Konovalov slab_flags_t kasan_never_merge(void); 301682ed089SAndrey Konovalov void kasan_cache_create(struct kmem_cache *cache, unsigned int *size, 302682ed089SAndrey Konovalov slab_flags_t *flags); 303f372bde9SAndrey Konovalov 3042bd926b4SAndrey Konovalov void kasan_cache_shrink(struct kmem_cache *cache); 3052bd926b4SAndrey Konovalov void kasan_cache_shutdown(struct kmem_cache *cache); 30626e760c9SWalter Wu void kasan_record_aux_stack(void *ptr); 3077cb3007cSMarco Elver void kasan_record_aux_stack_noalloc(void *ptr); 3082bd926b4SAndrey Konovalov 3092bd926b4SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC */ 3102bd926b4SAndrey Konovalov 311f372bde9SAndrey Konovalov /* Tag-based KASAN modes do not use per-object metadata. */ 3125d1ba310SFeng Tang static inline size_t kasan_metadata_size(struct kmem_cache *cache, 3135d1ba310SFeng Tang bool in_object) 314f372bde9SAndrey Konovalov { 315f372bde9SAndrey Konovalov return 0; 316f372bde9SAndrey Konovalov } 3173b7f8813SAndrey Konovalov /* And thus nothing prevents cache merging. */ 3183b7f8813SAndrey Konovalov static inline slab_flags_t kasan_never_merge(void) 3193b7f8813SAndrey Konovalov { 3203b7f8813SAndrey Konovalov return 0; 3213b7f8813SAndrey Konovalov } 322682ed089SAndrey Konovalov /* And no cache-related metadata initialization is required. */ 323682ed089SAndrey Konovalov static inline void kasan_cache_create(struct kmem_cache *cache, 324682ed089SAndrey Konovalov unsigned int *size, 325682ed089SAndrey Konovalov slab_flags_t *flags) {} 326f372bde9SAndrey Konovalov 3272bd926b4SAndrey Konovalov static inline void kasan_cache_shrink(struct kmem_cache *cache) {} 3282bd926b4SAndrey Konovalov static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} 32926e760c9SWalter Wu static inline void kasan_record_aux_stack(void *ptr) {} 3307cb3007cSMarco Elver static inline void kasan_record_aux_stack_noalloc(void *ptr) {} 3312bd926b4SAndrey Konovalov 3322bd926b4SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */ 3332bd926b4SAndrey Konovalov 3342e903b91SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) 3353c9e3aa1SAndrey Konovalov 336c0054c56SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 337c0054c56SAndrey Konovalov { 338c0054c56SAndrey Konovalov return (void *)arch_kasan_reset_tag(addr); 339c0054c56SAndrey Konovalov } 3403c9e3aa1SAndrey Konovalov 34149c6631dSVincenzo Frascino /** 34249c6631dSVincenzo Frascino * kasan_report - print a report about a bad memory access detected by KASAN 34349c6631dSVincenzo Frascino * @addr: address of the bad access 34449c6631dSVincenzo Frascino * @size: size of the bad access 34549c6631dSVincenzo Frascino * @is_write: whether the bad access is a write or a read 34649c6631dSVincenzo Frascino * @ip: instruction pointer for the accessibility check or the bad access itself 34749c6631dSVincenzo Frascino */ 348bb6e04a1SArnd Bergmann bool kasan_report(const void *addr, size_t size, 34941eea9cdSAndrey Konovalov bool is_write, unsigned long ip); 35041eea9cdSAndrey Konovalov 3512e903b91SAndrey Konovalov #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */ 3523c9e3aa1SAndrey Konovalov 3533c9e3aa1SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr) 3543c9e3aa1SAndrey Konovalov { 3553c9e3aa1SAndrey Konovalov return (void *)addr; 3563c9e3aa1SAndrey Konovalov } 3573c9e3aa1SAndrey Konovalov 3582e903b91SAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS*/ 3592e903b91SAndrey Konovalov 3608f7b5054SVincenzo Frascino #ifdef CONFIG_KASAN_HW_TAGS 3618f7b5054SVincenzo Frascino 3628f7b5054SVincenzo Frascino void kasan_report_async(void); 3638f7b5054SVincenzo Frascino 3648f7b5054SVincenzo Frascino #endif /* CONFIG_KASAN_HW_TAGS */ 3658f7b5054SVincenzo Frascino 3662e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS 3672e903b91SAndrey Konovalov void __init kasan_init_sw_tags(void); 3682e903b91SAndrey Konovalov #else 3692e903b91SAndrey Konovalov static inline void kasan_init_sw_tags(void) { } 3702e903b91SAndrey Konovalov #endif 3712e903b91SAndrey Konovalov 3722e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS 3732e903b91SAndrey Konovalov void kasan_init_hw_tags_cpu(void); 3742e903b91SAndrey Konovalov void __init kasan_init_hw_tags(void); 3752e903b91SAndrey Konovalov #else 3762e903b91SAndrey Konovalov static inline void kasan_init_hw_tags_cpu(void) { } 3772e903b91SAndrey Konovalov static inline void kasan_init_hw_tags(void) { } 3782e903b91SAndrey Konovalov #endif 379080eb83fSAndrey Konovalov 3803c5c3cfbSDaniel Axtens #ifdef CONFIG_KASAN_VMALLOC 3813b1a4a86SAndrey Konovalov 38223689e91SAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) 38323689e91SAndrey Konovalov 3845bd9bae2SAndrey Konovalov void kasan_populate_early_vm_area_shadow(void *start, unsigned long size); 385d98c9e83SAndrey Ryabinin int kasan_populate_vmalloc(unsigned long addr, unsigned long size); 3863c5c3cfbSDaniel Axtens void kasan_release_vmalloc(unsigned long start, unsigned long end, 3873c5c3cfbSDaniel Axtens unsigned long free_region_start, 3883c5c3cfbSDaniel Axtens unsigned long free_region_end); 3893b1a4a86SAndrey Konovalov 39023689e91SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 39123689e91SAndrey Konovalov 39223689e91SAndrey Konovalov static inline void kasan_populate_early_vm_area_shadow(void *start, 39323689e91SAndrey Konovalov unsigned long size) 39423689e91SAndrey Konovalov { } 39523689e91SAndrey Konovalov static inline int kasan_populate_vmalloc(unsigned long start, 396579fb0acSAndrey Konovalov unsigned long size) 397579fb0acSAndrey Konovalov { 39823689e91SAndrey Konovalov return 0; 39923689e91SAndrey Konovalov } 40023689e91SAndrey Konovalov static inline void kasan_release_vmalloc(unsigned long start, 40123689e91SAndrey Konovalov unsigned long end, 40223689e91SAndrey Konovalov unsigned long free_region_start, 40323689e91SAndrey Konovalov unsigned long free_region_end) { } 40423689e91SAndrey Konovalov 40523689e91SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ 40623689e91SAndrey Konovalov 40723689e91SAndrey Konovalov void *__kasan_unpoison_vmalloc(const void *start, unsigned long size, 40823689e91SAndrey Konovalov kasan_vmalloc_flags_t flags); 40923689e91SAndrey Konovalov static __always_inline void *kasan_unpoison_vmalloc(const void *start, 41023689e91SAndrey Konovalov unsigned long size, 41123689e91SAndrey Konovalov kasan_vmalloc_flags_t flags) 41223689e91SAndrey Konovalov { 413579fb0acSAndrey Konovalov if (kasan_enabled()) 41423689e91SAndrey Konovalov return __kasan_unpoison_vmalloc(start, size, flags); 4151d96320fSAndrey Konovalov return (void *)start; 416579fb0acSAndrey Konovalov } 417579fb0acSAndrey Konovalov 418579fb0acSAndrey Konovalov void __kasan_poison_vmalloc(const void *start, unsigned long size); 419579fb0acSAndrey Konovalov static __always_inline void kasan_poison_vmalloc(const void *start, 420579fb0acSAndrey Konovalov unsigned long size) 421579fb0acSAndrey Konovalov { 422579fb0acSAndrey Konovalov if (kasan_enabled()) 423579fb0acSAndrey Konovalov __kasan_poison_vmalloc(start, size); 424579fb0acSAndrey Konovalov } 4253252b1d8SKefeng Wang 4263b1a4a86SAndrey Konovalov #else /* CONFIG_KASAN_VMALLOC */ 4273b1a4a86SAndrey Konovalov 4285bd9bae2SAndrey Konovalov static inline void kasan_populate_early_vm_area_shadow(void *start, 4295bd9bae2SAndrey Konovalov unsigned long size) { } 430d98c9e83SAndrey Ryabinin static inline int kasan_populate_vmalloc(unsigned long start, 431d98c9e83SAndrey Ryabinin unsigned long size) 4323c5c3cfbSDaniel Axtens { 4333c5c3cfbSDaniel Axtens return 0; 4343c5c3cfbSDaniel Axtens } 4353c5c3cfbSDaniel Axtens static inline void kasan_release_vmalloc(unsigned long start, 4363c5c3cfbSDaniel Axtens unsigned long end, 4373c5c3cfbSDaniel Axtens unsigned long free_region_start, 4383c5c3cfbSDaniel Axtens unsigned long free_region_end) { } 4393b1a4a86SAndrey Konovalov 4401d96320fSAndrey Konovalov static inline void *kasan_unpoison_vmalloc(const void *start, 44123689e91SAndrey Konovalov unsigned long size, 44223689e91SAndrey Konovalov kasan_vmalloc_flags_t flags) 4431d96320fSAndrey Konovalov { 4441d96320fSAndrey Konovalov return (void *)start; 4451d96320fSAndrey Konovalov } 4465bd9bae2SAndrey Konovalov static inline void kasan_poison_vmalloc(const void *start, unsigned long size) 4473252b1d8SKefeng Wang { } 4483252b1d8SKefeng Wang 4493b1a4a86SAndrey Konovalov #endif /* CONFIG_KASAN_VMALLOC */ 4503b1a4a86SAndrey Konovalov 4510fea6e9aSAndrey Konovalov #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ 4520fea6e9aSAndrey Konovalov !defined(CONFIG_KASAN_VMALLOC) 4533b1a4a86SAndrey Konovalov 4543b1a4a86SAndrey Konovalov /* 45563840de2SAndrey Konovalov * These functions allocate and free shadow memory for kernel modules. 45663840de2SAndrey Konovalov * They are only required when KASAN_VMALLOC is not supported, as otherwise 45763840de2SAndrey Konovalov * shadow memory is allocated by the generic vmalloc handlers. 4583b1a4a86SAndrey Konovalov */ 45963840de2SAndrey Konovalov int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask); 46063840de2SAndrey Konovalov void kasan_free_module_shadow(const struct vm_struct *vm); 4613b1a4a86SAndrey Konovalov 4620fea6e9aSAndrey Konovalov #else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4633b1a4a86SAndrey Konovalov 46463840de2SAndrey Konovalov static inline int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask) { return 0; } 46563840de2SAndrey Konovalov static inline void kasan_free_module_shadow(const struct vm_struct *vm) {} 4663b1a4a86SAndrey Konovalov 4670fea6e9aSAndrey Konovalov #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ 4683c5c3cfbSDaniel Axtens 4692f004eeaSJann Horn #ifdef CONFIG_KASAN_INLINE 4702f004eeaSJann Horn void kasan_non_canonical_hook(unsigned long addr); 4712f004eeaSJann Horn #else /* CONFIG_KASAN_INLINE */ 4722f004eeaSJann Horn static inline void kasan_non_canonical_hook(unsigned long addr) { } 4732f004eeaSJann Horn #endif /* CONFIG_KASAN_INLINE */ 4742f004eeaSJann Horn 4750b24beccSAndrey Ryabinin #endif /* LINUX_KASAN_H */ 476