xref: /openbmc/linux/include/linux/kasan.h (revision 23689e91)
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 
2283c4e7a0SPatricia Alfonso /* kasan_data struct is used in KUnit tests for KASAN expected failures */
2383c4e7a0SPatricia Alfonso struct kunit_kasan_expectation {
2483c4e7a0SPatricia Alfonso 	bool report_found;
2583c4e7a0SPatricia Alfonso };
2683c4e7a0SPatricia Alfonso 
27d5750edfSAndrey Konovalov #endif
28d5750edfSAndrey Konovalov 
29*23689e91SAndrey Konovalov typedef unsigned int __bitwise kasan_vmalloc_flags_t;
30*23689e91SAndrey Konovalov 
31*23689e91SAndrey Konovalov #define KASAN_VMALLOC_NONE	0x00u
32*23689e91SAndrey Konovalov #define KASAN_VMALLOC_INIT	0x01u
33*23689e91SAndrey Konovalov #define KASAN_VMALLOC_VM_ALLOC	0x02u
34*23689e91SAndrey Konovalov 
35d5750edfSAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
36d5750edfSAndrey Konovalov 
37d5750edfSAndrey Konovalov #include <linux/pgtable.h>
38d5750edfSAndrey Konovalov 
39d5750edfSAndrey Konovalov /* Software KASAN implementations use shadow memory. */
40d5750edfSAndrey Konovalov 
41d5750edfSAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS
42a064cb00SAndrey Konovalov /* This matches KASAN_TAG_INVALID. */
43a064cb00SAndrey Konovalov #define KASAN_SHADOW_INIT 0xFE
44d5750edfSAndrey Konovalov #else
45d5750edfSAndrey Konovalov #define KASAN_SHADOW_INIT 0
46d5750edfSAndrey Konovalov #endif
47d5750edfSAndrey Konovalov 
4829970dc2SHailong Liu #ifndef PTE_HWTABLE_PTRS
4929970dc2SHailong Liu #define PTE_HWTABLE_PTRS 0
5029970dc2SHailong Liu #endif
5129970dc2SHailong Liu 
529577dd74SAndrey Konovalov extern unsigned char kasan_early_shadow_page[PAGE_SIZE];
53cb32c9c5SDaniel Axtens extern pte_t kasan_early_shadow_pte[MAX_PTRS_PER_PTE + PTE_HWTABLE_PTRS];
54cb32c9c5SDaniel Axtens extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD];
55cb32c9c5SDaniel Axtens extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD];
569577dd74SAndrey Konovalov extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
5769786cdbSAndrey Ryabinin 
589577dd74SAndrey Konovalov int kasan_populate_early_shadow(const void *shadow_start,
5969786cdbSAndrey Ryabinin 				const void *shadow_end);
6069786cdbSAndrey Ryabinin 
610b24beccSAndrey Ryabinin static inline void *kasan_mem_to_shadow(const void *addr)
620b24beccSAndrey Ryabinin {
630b24beccSAndrey Ryabinin 	return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
640b24beccSAndrey Ryabinin 		+ KASAN_SHADOW_OFFSET;
650b24beccSAndrey Ryabinin }
660b24beccSAndrey Ryabinin 
67d5750edfSAndrey Konovalov int kasan_add_zero_shadow(void *start, unsigned long size);
68d5750edfSAndrey Konovalov void kasan_remove_zero_shadow(void *start, unsigned long size);
69d5750edfSAndrey Konovalov 
70d73b4936SAndrey Konovalov /* Enable reporting bugs after kasan_disable_current() */
71d73b4936SAndrey Konovalov extern void kasan_enable_current(void);
72d73b4936SAndrey Konovalov 
73d73b4936SAndrey Konovalov /* Disable reporting bugs for current task */
74d73b4936SAndrey Konovalov extern void kasan_disable_current(void);
75d73b4936SAndrey Konovalov 
76d5750edfSAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
77d5750edfSAndrey Konovalov 
78d5750edfSAndrey Konovalov static inline int kasan_add_zero_shadow(void *start, unsigned long size)
79d5750edfSAndrey Konovalov {
80d5750edfSAndrey Konovalov 	return 0;
81d5750edfSAndrey Konovalov }
82d5750edfSAndrey Konovalov static inline void kasan_remove_zero_shadow(void *start,
83d5750edfSAndrey Konovalov 					unsigned long size)
84d5750edfSAndrey Konovalov {}
85d5750edfSAndrey Konovalov 
86d73b4936SAndrey Konovalov static inline void kasan_enable_current(void) {}
87d73b4936SAndrey Konovalov static inline void kasan_disable_current(void) {}
88d73b4936SAndrey Konovalov 
89d5750edfSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
90d5750edfSAndrey Konovalov 
9134303244SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS
92e86f8b09SAndrey Konovalov 
93e86f8b09SAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */
94e86f8b09SAndrey Konovalov 
95e86f8b09SAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */
96e86f8b09SAndrey Konovalov 
97e5af50a5SPeter Collingbourne static inline bool kasan_has_integrated_init(void)
98e5af50a5SPeter Collingbourne {
99e5af50a5SPeter Collingbourne 	return kasan_hw_tags_enabled();
100e5af50a5SPeter Collingbourne }
101e5af50a5SPeter Collingbourne 
1027a3b8353SPeter Collingbourne #ifdef CONFIG_KASAN
1037a3b8353SPeter Collingbourne 
1047a3b8353SPeter Collingbourne struct kasan_cache {
1057a3b8353SPeter Collingbourne 	int alloc_meta_offset;
1067a3b8353SPeter Collingbourne 	int free_meta_offset;
1077a3b8353SPeter Collingbourne 	bool is_kmalloc;
1087a3b8353SPeter Collingbourne };
1097a3b8353SPeter Collingbourne 
110e86f8b09SAndrey Konovalov slab_flags_t __kasan_never_merge(void);
111e86f8b09SAndrey Konovalov static __always_inline slab_flags_t kasan_never_merge(void)
112e86f8b09SAndrey Konovalov {
113e86f8b09SAndrey Konovalov 	if (kasan_enabled())
114e86f8b09SAndrey Konovalov 		return __kasan_never_merge();
115e86f8b09SAndrey Konovalov 	return 0;
116e86f8b09SAndrey Konovalov }
11734303244SAndrey Konovalov 
11834303244SAndrey Konovalov void __kasan_unpoison_range(const void *addr, size_t size);
11934303244SAndrey Konovalov static __always_inline void kasan_unpoison_range(const void *addr, size_t size)
12034303244SAndrey Konovalov {
12134303244SAndrey Konovalov 	if (kasan_enabled())
12234303244SAndrey Konovalov 		__kasan_unpoison_range(addr, size);
12334303244SAndrey Konovalov }
12434303244SAndrey Konovalov 
1257a3b8353SPeter Collingbourne void __kasan_poison_pages(struct page *page, unsigned int order, bool init);
1267a3b8353SPeter Collingbourne static __always_inline void kasan_poison_pages(struct page *page,
1271bb5eab3SAndrey Konovalov 						unsigned int order, bool init)
12834303244SAndrey Konovalov {
12934303244SAndrey Konovalov 	if (kasan_enabled())
1307a3b8353SPeter Collingbourne 		__kasan_poison_pages(page, order, init);
13134303244SAndrey Konovalov }
13234303244SAndrey Konovalov 
1337a3b8353SPeter Collingbourne void __kasan_unpoison_pages(struct page *page, unsigned int order, bool init);
1347a3b8353SPeter Collingbourne static __always_inline void kasan_unpoison_pages(struct page *page,
1351bb5eab3SAndrey Konovalov 						 unsigned int order, bool init)
13634303244SAndrey Konovalov {
13734303244SAndrey Konovalov 	if (kasan_enabled())
1387a3b8353SPeter Collingbourne 		__kasan_unpoison_pages(page, order, init);
13934303244SAndrey Konovalov }
14034303244SAndrey Konovalov 
14134303244SAndrey Konovalov void __kasan_cache_create(struct kmem_cache *cache, unsigned int *size,
14234303244SAndrey Konovalov 				slab_flags_t *flags);
14334303244SAndrey Konovalov static __always_inline void kasan_cache_create(struct kmem_cache *cache,
14434303244SAndrey Konovalov 				unsigned int *size, slab_flags_t *flags)
14534303244SAndrey Konovalov {
14634303244SAndrey Konovalov 	if (kasan_enabled())
14734303244SAndrey Konovalov 		__kasan_cache_create(cache, size, flags);
14834303244SAndrey Konovalov }
14934303244SAndrey Konovalov 
15092850134SAndrey Konovalov void __kasan_cache_create_kmalloc(struct kmem_cache *cache);
15192850134SAndrey Konovalov static __always_inline void kasan_cache_create_kmalloc(struct kmem_cache *cache)
15292850134SAndrey Konovalov {
15392850134SAndrey Konovalov 	if (kasan_enabled())
15492850134SAndrey Konovalov 		__kasan_cache_create_kmalloc(cache);
15592850134SAndrey Konovalov }
15692850134SAndrey Konovalov 
15734303244SAndrey Konovalov size_t __kasan_metadata_size(struct kmem_cache *cache);
15834303244SAndrey Konovalov static __always_inline size_t kasan_metadata_size(struct kmem_cache *cache)
15934303244SAndrey Konovalov {
16034303244SAndrey Konovalov 	if (kasan_enabled())
16134303244SAndrey Konovalov 		return __kasan_metadata_size(cache);
16234303244SAndrey Konovalov 	return 0;
16334303244SAndrey Konovalov }
16434303244SAndrey Konovalov 
1656e48a966SMatthew Wilcox (Oracle) void __kasan_poison_slab(struct slab *slab);
1666e48a966SMatthew Wilcox (Oracle) static __always_inline void kasan_poison_slab(struct slab *slab)
16734303244SAndrey Konovalov {
16834303244SAndrey Konovalov 	if (kasan_enabled())
1696e48a966SMatthew Wilcox (Oracle) 		__kasan_poison_slab(slab);
17034303244SAndrey Konovalov }
17134303244SAndrey Konovalov 
17234303244SAndrey Konovalov void __kasan_unpoison_object_data(struct kmem_cache *cache, void *object);
17334303244SAndrey Konovalov static __always_inline void kasan_unpoison_object_data(struct kmem_cache *cache,
17434303244SAndrey Konovalov 							void *object)
17534303244SAndrey Konovalov {
17634303244SAndrey Konovalov 	if (kasan_enabled())
17734303244SAndrey Konovalov 		__kasan_unpoison_object_data(cache, object);
17834303244SAndrey Konovalov }
17934303244SAndrey Konovalov 
18034303244SAndrey Konovalov void __kasan_poison_object_data(struct kmem_cache *cache, void *object);
18134303244SAndrey Konovalov static __always_inline void kasan_poison_object_data(struct kmem_cache *cache,
18234303244SAndrey Konovalov 							void *object)
18334303244SAndrey Konovalov {
18434303244SAndrey Konovalov 	if (kasan_enabled())
18534303244SAndrey Konovalov 		__kasan_poison_object_data(cache, object);
18634303244SAndrey Konovalov }
18734303244SAndrey Konovalov 
18834303244SAndrey Konovalov void * __must_check __kasan_init_slab_obj(struct kmem_cache *cache,
18934303244SAndrey Konovalov 					  const void *object);
19034303244SAndrey Konovalov static __always_inline void * __must_check kasan_init_slab_obj(
19134303244SAndrey Konovalov 				struct kmem_cache *cache, const void *object)
19234303244SAndrey Konovalov {
19334303244SAndrey Konovalov 	if (kasan_enabled())
19434303244SAndrey Konovalov 		return __kasan_init_slab_obj(cache, object);
19534303244SAndrey Konovalov 	return (void *)object;
19634303244SAndrey Konovalov }
19734303244SAndrey Konovalov 
198d57a964eSAndrey Konovalov bool __kasan_slab_free(struct kmem_cache *s, void *object,
199d57a964eSAndrey Konovalov 			unsigned long ip, bool init);
200d57a964eSAndrey Konovalov static __always_inline bool kasan_slab_free(struct kmem_cache *s,
201d57a964eSAndrey Konovalov 						void *object, bool init)
20234303244SAndrey Konovalov {
20334303244SAndrey Konovalov 	if (kasan_enabled())
204d57a964eSAndrey Konovalov 		return __kasan_slab_free(s, object, _RET_IP_, init);
20534303244SAndrey Konovalov 	return false;
20634303244SAndrey Konovalov }
20734303244SAndrey Konovalov 
208200072ceSAndrey Konovalov void __kasan_kfree_large(void *ptr, unsigned long ip);
209200072ceSAndrey Konovalov static __always_inline void kasan_kfree_large(void *ptr)
210200072ceSAndrey Konovalov {
211200072ceSAndrey Konovalov 	if (kasan_enabled())
212200072ceSAndrey Konovalov 		__kasan_kfree_large(ptr, _RET_IP_);
213200072ceSAndrey Konovalov }
214200072ceSAndrey Konovalov 
215eeb3160cSAndrey Konovalov void __kasan_slab_free_mempool(void *ptr, unsigned long ip);
216027b37b5SAndrey Konovalov static __always_inline void kasan_slab_free_mempool(void *ptr)
217eeb3160cSAndrey Konovalov {
218eeb3160cSAndrey Konovalov 	if (kasan_enabled())
219027b37b5SAndrey Konovalov 		__kasan_slab_free_mempool(ptr, _RET_IP_);
220eeb3160cSAndrey Konovalov }
221eeb3160cSAndrey Konovalov 
22234303244SAndrey Konovalov void * __must_check __kasan_slab_alloc(struct kmem_cache *s,
223da844b78SAndrey Konovalov 				       void *object, gfp_t flags, bool init);
22434303244SAndrey Konovalov static __always_inline void * __must_check kasan_slab_alloc(
225da844b78SAndrey Konovalov 		struct kmem_cache *s, void *object, gfp_t flags, bool init)
22634303244SAndrey Konovalov {
22734303244SAndrey Konovalov 	if (kasan_enabled())
228da844b78SAndrey Konovalov 		return __kasan_slab_alloc(s, object, flags, init);
22934303244SAndrey Konovalov 	return object;
23034303244SAndrey Konovalov }
23134303244SAndrey Konovalov 
23234303244SAndrey Konovalov void * __must_check __kasan_kmalloc(struct kmem_cache *s, const void *object,
23334303244SAndrey Konovalov 				    size_t size, gfp_t flags);
23434303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc(struct kmem_cache *s,
23534303244SAndrey Konovalov 				const void *object, size_t size, gfp_t flags)
23634303244SAndrey Konovalov {
23734303244SAndrey Konovalov 	if (kasan_enabled())
23834303244SAndrey Konovalov 		return __kasan_kmalloc(s, object, size, flags);
23934303244SAndrey Konovalov 	return (void *)object;
24034303244SAndrey Konovalov }
24134303244SAndrey Konovalov 
24234303244SAndrey Konovalov void * __must_check __kasan_kmalloc_large(const void *ptr,
24334303244SAndrey Konovalov 					  size_t size, gfp_t flags);
24434303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc_large(const void *ptr,
24534303244SAndrey Konovalov 						      size_t size, gfp_t flags)
24634303244SAndrey Konovalov {
24734303244SAndrey Konovalov 	if (kasan_enabled())
24834303244SAndrey Konovalov 		return __kasan_kmalloc_large(ptr, size, flags);
24934303244SAndrey Konovalov 	return (void *)ptr;
25034303244SAndrey Konovalov }
25134303244SAndrey Konovalov 
25234303244SAndrey Konovalov void * __must_check __kasan_krealloc(const void *object,
25334303244SAndrey Konovalov 				     size_t new_size, gfp_t flags);
25434303244SAndrey Konovalov static __always_inline void * __must_check kasan_krealloc(const void *object,
25534303244SAndrey Konovalov 						 size_t new_size, gfp_t flags)
25634303244SAndrey Konovalov {
25734303244SAndrey Konovalov 	if (kasan_enabled())
25834303244SAndrey Konovalov 		return __kasan_krealloc(object, new_size, flags);
25934303244SAndrey Konovalov 	return (void *)object;
26034303244SAndrey Konovalov }
26134303244SAndrey Konovalov 
262611806b4SAndrey Konovalov /*
263611806b4SAndrey Konovalov  * Unlike kasan_check_read/write(), kasan_check_byte() is performed even for
264611806b4SAndrey Konovalov  * the hardware tag-based mode that doesn't rely on compiler instrumentation.
265611806b4SAndrey Konovalov  */
266611806b4SAndrey Konovalov bool __kasan_check_byte(const void *addr, unsigned long ip);
267611806b4SAndrey Konovalov static __always_inline bool kasan_check_byte(const void *addr)
268611806b4SAndrey Konovalov {
269611806b4SAndrey Konovalov 	if (kasan_enabled())
270611806b4SAndrey Konovalov 		return __kasan_check_byte(addr, _RET_IP_);
271611806b4SAndrey Konovalov 	return true;
272611806b4SAndrey Konovalov }
273611806b4SAndrey Konovalov 
274611806b4SAndrey Konovalov 
275b0845ce5SMark Rutland bool kasan_save_enable_multi_shot(void);
276b0845ce5SMark Rutland void kasan_restore_multi_shot(bool enabled);
277b0845ce5SMark Rutland 
2780b24beccSAndrey Ryabinin #else /* CONFIG_KASAN */
2790b24beccSAndrey Ryabinin 
280e86f8b09SAndrey Konovalov static inline slab_flags_t kasan_never_merge(void)
281e86f8b09SAndrey Konovalov {
282e86f8b09SAndrey Konovalov 	return 0;
283e86f8b09SAndrey Konovalov }
284cebd0eb2SAndrey Konovalov static inline void kasan_unpoison_range(const void *address, size_t size) {}
2857a3b8353SPeter Collingbourne static inline void kasan_poison_pages(struct page *page, unsigned int order,
2867a3b8353SPeter Collingbourne 				      bool init) {}
2877a3b8353SPeter Collingbourne static inline void kasan_unpoison_pages(struct page *page, unsigned int order,
2887a3b8353SPeter Collingbourne 					bool init) {}
2897ed2f9e6SAlexander Potapenko static inline void kasan_cache_create(struct kmem_cache *cache,
290be4a7988SAlexey Dobriyan 				      unsigned int *size,
291d50112edSAlexey Dobriyan 				      slab_flags_t *flags) {}
29292850134SAndrey Konovalov static inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) {}
29334303244SAndrey Konovalov static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; }
2946e48a966SMatthew Wilcox (Oracle) static inline void kasan_poison_slab(struct slab *slab) {}
2950316bec2SAndrey Ryabinin static inline void kasan_unpoison_object_data(struct kmem_cache *cache,
2960316bec2SAndrey Ryabinin 					void *object) {}
2970316bec2SAndrey Ryabinin static inline void kasan_poison_object_data(struct kmem_cache *cache,
2980316bec2SAndrey Ryabinin 					void *object) {}
2990116523cSAndrey Konovalov static inline void *kasan_init_slab_obj(struct kmem_cache *cache,
3000116523cSAndrey Konovalov 				const void *object)
3010116523cSAndrey Konovalov {
3020116523cSAndrey Konovalov 	return (void *)object;
3030116523cSAndrey Konovalov }
304d57a964eSAndrey Konovalov static inline bool kasan_slab_free(struct kmem_cache *s, void *object, bool init)
3050116523cSAndrey Konovalov {
30634303244SAndrey Konovalov 	return false;
3070116523cSAndrey Konovalov }
308200072ceSAndrey Konovalov static inline void kasan_kfree_large(void *ptr) {}
309027b37b5SAndrey Konovalov static inline void kasan_slab_free_mempool(void *ptr) {}
31034303244SAndrey Konovalov static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object,
311da844b78SAndrey Konovalov 				   gfp_t flags, bool init)
31234303244SAndrey Konovalov {
31334303244SAndrey Konovalov 	return object;
31434303244SAndrey Konovalov }
3150116523cSAndrey Konovalov static inline void *kasan_kmalloc(struct kmem_cache *s, const void *object,
3160116523cSAndrey Konovalov 				size_t size, gfp_t flags)
3170116523cSAndrey Konovalov {
3180116523cSAndrey Konovalov 	return (void *)object;
3190116523cSAndrey Konovalov }
32034303244SAndrey Konovalov static inline void *kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags)
32134303244SAndrey Konovalov {
32234303244SAndrey Konovalov 	return (void *)ptr;
32334303244SAndrey Konovalov }
3240116523cSAndrey Konovalov static inline void *kasan_krealloc(const void *object, size_t new_size,
3250116523cSAndrey Konovalov 				 gfp_t flags)
3260116523cSAndrey Konovalov {
3270116523cSAndrey Konovalov 	return (void *)object;
3280116523cSAndrey Konovalov }
329611806b4SAndrey Konovalov static inline bool kasan_check_byte(const void *address)
330611806b4SAndrey Konovalov {
331611806b4SAndrey Konovalov 	return true;
332611806b4SAndrey Konovalov }
3339b75a867SAndrey Ryabinin 
3340b24beccSAndrey Ryabinin #endif /* CONFIG_KASAN */
3350b24beccSAndrey Ryabinin 
33602c58773SWalter Wu #if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK)
337d56a9ef8SAndrey Konovalov void kasan_unpoison_task_stack(struct task_struct *task);
338d56a9ef8SAndrey Konovalov #else
339d56a9ef8SAndrey Konovalov static inline void kasan_unpoison_task_stack(struct task_struct *task) {}
340d56a9ef8SAndrey Konovalov #endif
341d56a9ef8SAndrey Konovalov 
3422bd926b4SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC
3432bd926b4SAndrey Konovalov 
3442bd926b4SAndrey Konovalov void kasan_cache_shrink(struct kmem_cache *cache);
3452bd926b4SAndrey Konovalov void kasan_cache_shutdown(struct kmem_cache *cache);
34626e760c9SWalter Wu void kasan_record_aux_stack(void *ptr);
3477cb3007cSMarco Elver void kasan_record_aux_stack_noalloc(void *ptr);
3482bd926b4SAndrey Konovalov 
3492bd926b4SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC */
3502bd926b4SAndrey Konovalov 
3512bd926b4SAndrey Konovalov static inline void kasan_cache_shrink(struct kmem_cache *cache) {}
3522bd926b4SAndrey Konovalov static inline void kasan_cache_shutdown(struct kmem_cache *cache) {}
35326e760c9SWalter Wu static inline void kasan_record_aux_stack(void *ptr) {}
3547cb3007cSMarco Elver static inline void kasan_record_aux_stack_noalloc(void *ptr) {}
3552bd926b4SAndrey Konovalov 
3562bd926b4SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */
3572bd926b4SAndrey Konovalov 
3582e903b91SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
3593c9e3aa1SAndrey Konovalov 
360c0054c56SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr)
361c0054c56SAndrey Konovalov {
362c0054c56SAndrey Konovalov 	return (void *)arch_kasan_reset_tag(addr);
363c0054c56SAndrey Konovalov }
3643c9e3aa1SAndrey Konovalov 
36549c6631dSVincenzo Frascino /**
36649c6631dSVincenzo Frascino  * kasan_report - print a report about a bad memory access detected by KASAN
36749c6631dSVincenzo Frascino  * @addr: address of the bad access
36849c6631dSVincenzo Frascino  * @size: size of the bad access
36949c6631dSVincenzo Frascino  * @is_write: whether the bad access is a write or a read
37049c6631dSVincenzo Frascino  * @ip: instruction pointer for the accessibility check or the bad access itself
37149c6631dSVincenzo Frascino  */
3728cceeff4SWalter Wu bool kasan_report(unsigned long addr, size_t size,
37341eea9cdSAndrey Konovalov 		bool is_write, unsigned long ip);
37441eea9cdSAndrey Konovalov 
3752e903b91SAndrey Konovalov #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
3763c9e3aa1SAndrey Konovalov 
3773c9e3aa1SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr)
3783c9e3aa1SAndrey Konovalov {
3793c9e3aa1SAndrey Konovalov 	return (void *)addr;
3803c9e3aa1SAndrey Konovalov }
3813c9e3aa1SAndrey Konovalov 
3822e903b91SAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS*/
3832e903b91SAndrey Konovalov 
3848f7b5054SVincenzo Frascino #ifdef CONFIG_KASAN_HW_TAGS
3858f7b5054SVincenzo Frascino 
3868f7b5054SVincenzo Frascino void kasan_report_async(void);
3878f7b5054SVincenzo Frascino 
3888f7b5054SVincenzo Frascino #endif /* CONFIG_KASAN_HW_TAGS */
3898f7b5054SVincenzo Frascino 
3902e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS
3912e903b91SAndrey Konovalov void __init kasan_init_sw_tags(void);
3922e903b91SAndrey Konovalov #else
3932e903b91SAndrey Konovalov static inline void kasan_init_sw_tags(void) { }
3942e903b91SAndrey Konovalov #endif
3952e903b91SAndrey Konovalov 
3962e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS
3972e903b91SAndrey Konovalov void kasan_init_hw_tags_cpu(void);
3982e903b91SAndrey Konovalov void __init kasan_init_hw_tags(void);
3992e903b91SAndrey Konovalov #else
4002e903b91SAndrey Konovalov static inline void kasan_init_hw_tags_cpu(void) { }
4012e903b91SAndrey Konovalov static inline void kasan_init_hw_tags(void) { }
4022e903b91SAndrey Konovalov #endif
403080eb83fSAndrey Konovalov 
4043c5c3cfbSDaniel Axtens #ifdef CONFIG_KASAN_VMALLOC
4053b1a4a86SAndrey Konovalov 
406*23689e91SAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
407*23689e91SAndrey Konovalov 
4085bd9bae2SAndrey Konovalov void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
409d98c9e83SAndrey Ryabinin int kasan_populate_vmalloc(unsigned long addr, unsigned long size);
4103c5c3cfbSDaniel Axtens void kasan_release_vmalloc(unsigned long start, unsigned long end,
4113c5c3cfbSDaniel Axtens 			   unsigned long free_region_start,
4123c5c3cfbSDaniel Axtens 			   unsigned long free_region_end);
4133b1a4a86SAndrey Konovalov 
414*23689e91SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
415*23689e91SAndrey Konovalov 
416*23689e91SAndrey Konovalov static inline void kasan_populate_early_vm_area_shadow(void *start,
417*23689e91SAndrey Konovalov 						       unsigned long size)
418*23689e91SAndrey Konovalov { }
419*23689e91SAndrey Konovalov static inline int kasan_populate_vmalloc(unsigned long start,
420579fb0acSAndrey Konovalov 					unsigned long size)
421579fb0acSAndrey Konovalov {
422*23689e91SAndrey Konovalov 	return 0;
423*23689e91SAndrey Konovalov }
424*23689e91SAndrey Konovalov static inline void kasan_release_vmalloc(unsigned long start,
425*23689e91SAndrey Konovalov 					 unsigned long end,
426*23689e91SAndrey Konovalov 					 unsigned long free_region_start,
427*23689e91SAndrey Konovalov 					 unsigned long free_region_end) { }
428*23689e91SAndrey Konovalov 
429*23689e91SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
430*23689e91SAndrey Konovalov 
431*23689e91SAndrey Konovalov void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
432*23689e91SAndrey Konovalov 			       kasan_vmalloc_flags_t flags);
433*23689e91SAndrey Konovalov static __always_inline void *kasan_unpoison_vmalloc(const void *start,
434*23689e91SAndrey Konovalov 						unsigned long size,
435*23689e91SAndrey Konovalov 						kasan_vmalloc_flags_t flags)
436*23689e91SAndrey Konovalov {
437579fb0acSAndrey Konovalov 	if (kasan_enabled())
438*23689e91SAndrey Konovalov 		return __kasan_unpoison_vmalloc(start, size, flags);
4391d96320fSAndrey Konovalov 	return (void *)start;
440579fb0acSAndrey Konovalov }
441579fb0acSAndrey Konovalov 
442579fb0acSAndrey Konovalov void __kasan_poison_vmalloc(const void *start, unsigned long size);
443579fb0acSAndrey Konovalov static __always_inline void kasan_poison_vmalloc(const void *start,
444579fb0acSAndrey Konovalov 						 unsigned long size)
445579fb0acSAndrey Konovalov {
446579fb0acSAndrey Konovalov 	if (kasan_enabled())
447579fb0acSAndrey Konovalov 		__kasan_poison_vmalloc(start, size);
448579fb0acSAndrey Konovalov }
4493252b1d8SKefeng Wang 
4503b1a4a86SAndrey Konovalov #else /* CONFIG_KASAN_VMALLOC */
4513b1a4a86SAndrey Konovalov 
4525bd9bae2SAndrey Konovalov static inline void kasan_populate_early_vm_area_shadow(void *start,
4535bd9bae2SAndrey Konovalov 						       unsigned long size) { }
454d98c9e83SAndrey Ryabinin static inline int kasan_populate_vmalloc(unsigned long start,
455d98c9e83SAndrey Ryabinin 					unsigned long size)
4563c5c3cfbSDaniel Axtens {
4573c5c3cfbSDaniel Axtens 	return 0;
4583c5c3cfbSDaniel Axtens }
4593c5c3cfbSDaniel Axtens static inline void kasan_release_vmalloc(unsigned long start,
4603c5c3cfbSDaniel Axtens 					 unsigned long end,
4613c5c3cfbSDaniel Axtens 					 unsigned long free_region_start,
4623c5c3cfbSDaniel Axtens 					 unsigned long free_region_end) { }
4633b1a4a86SAndrey Konovalov 
4641d96320fSAndrey Konovalov static inline void *kasan_unpoison_vmalloc(const void *start,
465*23689e91SAndrey Konovalov 					   unsigned long size,
466*23689e91SAndrey Konovalov 					   kasan_vmalloc_flags_t flags)
4671d96320fSAndrey Konovalov {
4681d96320fSAndrey Konovalov 	return (void *)start;
4691d96320fSAndrey Konovalov }
4705bd9bae2SAndrey Konovalov static inline void kasan_poison_vmalloc(const void *start, unsigned long size)
4713252b1d8SKefeng Wang { }
4723252b1d8SKefeng Wang 
4733b1a4a86SAndrey Konovalov #endif /* CONFIG_KASAN_VMALLOC */
4743b1a4a86SAndrey Konovalov 
4750fea6e9aSAndrey Konovalov #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \
4760fea6e9aSAndrey Konovalov 		!defined(CONFIG_KASAN_VMALLOC)
4773b1a4a86SAndrey Konovalov 
4783b1a4a86SAndrey Konovalov /*
47963840de2SAndrey Konovalov  * These functions allocate and free shadow memory for kernel modules.
48063840de2SAndrey Konovalov  * They are only required when KASAN_VMALLOC is not supported, as otherwise
48163840de2SAndrey Konovalov  * shadow memory is allocated by the generic vmalloc handlers.
4823b1a4a86SAndrey Konovalov  */
48363840de2SAndrey Konovalov int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask);
48463840de2SAndrey Konovalov void kasan_free_module_shadow(const struct vm_struct *vm);
4853b1a4a86SAndrey Konovalov 
4860fea6e9aSAndrey Konovalov #else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
4873b1a4a86SAndrey Konovalov 
48863840de2SAndrey Konovalov static inline int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask) { return 0; }
48963840de2SAndrey Konovalov static inline void kasan_free_module_shadow(const struct vm_struct *vm) {}
4903b1a4a86SAndrey Konovalov 
4910fea6e9aSAndrey Konovalov #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
4923c5c3cfbSDaniel Axtens 
4932f004eeaSJann Horn #ifdef CONFIG_KASAN_INLINE
4942f004eeaSJann Horn void kasan_non_canonical_hook(unsigned long addr);
4952f004eeaSJann Horn #else /* CONFIG_KASAN_INLINE */
4962f004eeaSJann Horn static inline void kasan_non_canonical_hook(unsigned long addr) { }
4972f004eeaSJann Horn #endif /* CONFIG_KASAN_INLINE */
4982f004eeaSJann Horn 
4990b24beccSAndrey Ryabinin #endif /* LINUX_KASAN_H */
500