xref: /openbmc/linux/include/linux/kasan.h (revision f372bde9)
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