xref: /openbmc/linux/include/linux/kasan.h (revision f9b5e46f)
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>
6*f9b5e46fSPeter 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 
29d5750edfSAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
30d5750edfSAndrey Konovalov 
31d5750edfSAndrey Konovalov #include <linux/pgtable.h>
32d5750edfSAndrey Konovalov 
33d5750edfSAndrey Konovalov /* Software KASAN implementations use shadow memory. */
34d5750edfSAndrey Konovalov 
35d5750edfSAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS
36a064cb00SAndrey Konovalov /* This matches KASAN_TAG_INVALID. */
37a064cb00SAndrey Konovalov #define KASAN_SHADOW_INIT 0xFE
38d5750edfSAndrey Konovalov #else
39d5750edfSAndrey Konovalov #define KASAN_SHADOW_INIT 0
40d5750edfSAndrey Konovalov #endif
41d5750edfSAndrey Konovalov 
4229970dc2SHailong Liu #ifndef PTE_HWTABLE_PTRS
4329970dc2SHailong Liu #define PTE_HWTABLE_PTRS 0
4429970dc2SHailong Liu #endif
4529970dc2SHailong Liu 
469577dd74SAndrey Konovalov extern unsigned char kasan_early_shadow_page[PAGE_SIZE];
47cb32c9c5SDaniel Axtens extern pte_t kasan_early_shadow_pte[MAX_PTRS_PER_PTE + PTE_HWTABLE_PTRS];
48cb32c9c5SDaniel Axtens extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD];
49cb32c9c5SDaniel Axtens extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD];
509577dd74SAndrey Konovalov extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
5169786cdbSAndrey Ryabinin 
529577dd74SAndrey Konovalov int kasan_populate_early_shadow(const void *shadow_start,
5369786cdbSAndrey Ryabinin 				const void *shadow_end);
5469786cdbSAndrey Ryabinin 
550b24beccSAndrey Ryabinin static inline void *kasan_mem_to_shadow(const void *addr)
560b24beccSAndrey Ryabinin {
570b24beccSAndrey Ryabinin 	return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
580b24beccSAndrey Ryabinin 		+ KASAN_SHADOW_OFFSET;
590b24beccSAndrey Ryabinin }
600b24beccSAndrey Ryabinin 
61d5750edfSAndrey Konovalov int kasan_add_zero_shadow(void *start, unsigned long size);
62d5750edfSAndrey Konovalov void kasan_remove_zero_shadow(void *start, unsigned long size);
63d5750edfSAndrey Konovalov 
64d73b4936SAndrey Konovalov /* Enable reporting bugs after kasan_disable_current() */
65d73b4936SAndrey Konovalov extern void kasan_enable_current(void);
66d73b4936SAndrey Konovalov 
67d73b4936SAndrey Konovalov /* Disable reporting bugs for current task */
68d73b4936SAndrey Konovalov extern void kasan_disable_current(void);
69d73b4936SAndrey Konovalov 
70d5750edfSAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
71d5750edfSAndrey Konovalov 
72d5750edfSAndrey Konovalov static inline int kasan_add_zero_shadow(void *start, unsigned long size)
73d5750edfSAndrey Konovalov {
74d5750edfSAndrey Konovalov 	return 0;
75d5750edfSAndrey Konovalov }
76d5750edfSAndrey Konovalov static inline void kasan_remove_zero_shadow(void *start,
77d5750edfSAndrey Konovalov 					unsigned long size)
78d5750edfSAndrey Konovalov {}
79d5750edfSAndrey Konovalov 
80d73b4936SAndrey Konovalov static inline void kasan_enable_current(void) {}
81d73b4936SAndrey Konovalov static inline void kasan_disable_current(void) {}
82d73b4936SAndrey Konovalov 
83d5750edfSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
84d5750edfSAndrey Konovalov 
8534303244SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS
86e86f8b09SAndrey Konovalov 
877a3b8353SPeter Collingbourne void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags);
887a3b8353SPeter Collingbourne void kasan_free_pages(struct page *page, unsigned int order);
897a3b8353SPeter Collingbourne 
90e86f8b09SAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */
91e86f8b09SAndrey Konovalov 
927a3b8353SPeter Collingbourne static __always_inline void kasan_alloc_pages(struct page *page,
937a3b8353SPeter Collingbourne 					      unsigned int order, gfp_t flags)
947a3b8353SPeter Collingbourne {
957a3b8353SPeter Collingbourne 	/* Only available for integrated init. */
967a3b8353SPeter Collingbourne 	BUILD_BUG();
977a3b8353SPeter Collingbourne }
987a3b8353SPeter Collingbourne 
997a3b8353SPeter Collingbourne static __always_inline void kasan_free_pages(struct page *page,
1007a3b8353SPeter Collingbourne 					     unsigned int order)
1017a3b8353SPeter Collingbourne {
1027a3b8353SPeter Collingbourne 	/* Only available for integrated init. */
1037a3b8353SPeter Collingbourne 	BUILD_BUG();
1047a3b8353SPeter Collingbourne }
1057a3b8353SPeter Collingbourne 
106e86f8b09SAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */
107e86f8b09SAndrey Konovalov 
108e5af50a5SPeter Collingbourne static inline bool kasan_has_integrated_init(void)
109e5af50a5SPeter Collingbourne {
110e5af50a5SPeter Collingbourne 	return kasan_hw_tags_enabled();
111e5af50a5SPeter Collingbourne }
112e5af50a5SPeter Collingbourne 
1137a3b8353SPeter Collingbourne #ifdef CONFIG_KASAN
1147a3b8353SPeter Collingbourne 
1157a3b8353SPeter Collingbourne struct kasan_cache {
1167a3b8353SPeter Collingbourne 	int alloc_meta_offset;
1177a3b8353SPeter Collingbourne 	int free_meta_offset;
1187a3b8353SPeter Collingbourne 	bool is_kmalloc;
1197a3b8353SPeter Collingbourne };
1207a3b8353SPeter Collingbourne 
121e86f8b09SAndrey Konovalov slab_flags_t __kasan_never_merge(void);
122e86f8b09SAndrey Konovalov static __always_inline slab_flags_t kasan_never_merge(void)
123e86f8b09SAndrey Konovalov {
124e86f8b09SAndrey Konovalov 	if (kasan_enabled())
125e86f8b09SAndrey Konovalov 		return __kasan_never_merge();
126e86f8b09SAndrey Konovalov 	return 0;
127e86f8b09SAndrey Konovalov }
12834303244SAndrey Konovalov 
12934303244SAndrey Konovalov void __kasan_unpoison_range(const void *addr, size_t size);
13034303244SAndrey Konovalov static __always_inline void kasan_unpoison_range(const void *addr, size_t size)
13134303244SAndrey Konovalov {
13234303244SAndrey Konovalov 	if (kasan_enabled())
13334303244SAndrey Konovalov 		__kasan_unpoison_range(addr, size);
13434303244SAndrey Konovalov }
13534303244SAndrey Konovalov 
1367a3b8353SPeter Collingbourne void __kasan_poison_pages(struct page *page, unsigned int order, bool init);
1377a3b8353SPeter Collingbourne static __always_inline void kasan_poison_pages(struct page *page,
1381bb5eab3SAndrey Konovalov 						unsigned int order, bool init)
13934303244SAndrey Konovalov {
14034303244SAndrey Konovalov 	if (kasan_enabled())
1417a3b8353SPeter Collingbourne 		__kasan_poison_pages(page, order, init);
14234303244SAndrey Konovalov }
14334303244SAndrey Konovalov 
1447a3b8353SPeter Collingbourne void __kasan_unpoison_pages(struct page *page, unsigned int order, bool init);
1457a3b8353SPeter Collingbourne static __always_inline void kasan_unpoison_pages(struct page *page,
1461bb5eab3SAndrey Konovalov 						 unsigned int order, bool init)
14734303244SAndrey Konovalov {
14834303244SAndrey Konovalov 	if (kasan_enabled())
1497a3b8353SPeter Collingbourne 		__kasan_unpoison_pages(page, order, init);
15034303244SAndrey Konovalov }
15134303244SAndrey Konovalov 
15234303244SAndrey Konovalov void __kasan_cache_create(struct kmem_cache *cache, unsigned int *size,
15334303244SAndrey Konovalov 				slab_flags_t *flags);
15434303244SAndrey Konovalov static __always_inline void kasan_cache_create(struct kmem_cache *cache,
15534303244SAndrey Konovalov 				unsigned int *size, slab_flags_t *flags)
15634303244SAndrey Konovalov {
15734303244SAndrey Konovalov 	if (kasan_enabled())
15834303244SAndrey Konovalov 		__kasan_cache_create(cache, size, flags);
15934303244SAndrey Konovalov }
16034303244SAndrey Konovalov 
16192850134SAndrey Konovalov void __kasan_cache_create_kmalloc(struct kmem_cache *cache);
16292850134SAndrey Konovalov static __always_inline void kasan_cache_create_kmalloc(struct kmem_cache *cache)
16392850134SAndrey Konovalov {
16492850134SAndrey Konovalov 	if (kasan_enabled())
16592850134SAndrey Konovalov 		__kasan_cache_create_kmalloc(cache);
16692850134SAndrey Konovalov }
16792850134SAndrey Konovalov 
16834303244SAndrey Konovalov size_t __kasan_metadata_size(struct kmem_cache *cache);
16934303244SAndrey Konovalov static __always_inline size_t kasan_metadata_size(struct kmem_cache *cache)
17034303244SAndrey Konovalov {
17134303244SAndrey Konovalov 	if (kasan_enabled())
17234303244SAndrey Konovalov 		return __kasan_metadata_size(cache);
17334303244SAndrey Konovalov 	return 0;
17434303244SAndrey Konovalov }
17534303244SAndrey Konovalov 
1766e48a966SMatthew Wilcox (Oracle) void __kasan_poison_slab(struct slab *slab);
1776e48a966SMatthew Wilcox (Oracle) static __always_inline void kasan_poison_slab(struct slab *slab)
17834303244SAndrey Konovalov {
17934303244SAndrey Konovalov 	if (kasan_enabled())
1806e48a966SMatthew Wilcox (Oracle) 		__kasan_poison_slab(slab);
18134303244SAndrey Konovalov }
18234303244SAndrey Konovalov 
18334303244SAndrey Konovalov void __kasan_unpoison_object_data(struct kmem_cache *cache, void *object);
18434303244SAndrey Konovalov static __always_inline void kasan_unpoison_object_data(struct kmem_cache *cache,
18534303244SAndrey Konovalov 							void *object)
18634303244SAndrey Konovalov {
18734303244SAndrey Konovalov 	if (kasan_enabled())
18834303244SAndrey Konovalov 		__kasan_unpoison_object_data(cache, object);
18934303244SAndrey Konovalov }
19034303244SAndrey Konovalov 
19134303244SAndrey Konovalov void __kasan_poison_object_data(struct kmem_cache *cache, void *object);
19234303244SAndrey Konovalov static __always_inline void kasan_poison_object_data(struct kmem_cache *cache,
19334303244SAndrey Konovalov 							void *object)
19434303244SAndrey Konovalov {
19534303244SAndrey Konovalov 	if (kasan_enabled())
19634303244SAndrey Konovalov 		__kasan_poison_object_data(cache, object);
19734303244SAndrey Konovalov }
19834303244SAndrey Konovalov 
19934303244SAndrey Konovalov void * __must_check __kasan_init_slab_obj(struct kmem_cache *cache,
20034303244SAndrey Konovalov 					  const void *object);
20134303244SAndrey Konovalov static __always_inline void * __must_check kasan_init_slab_obj(
20234303244SAndrey Konovalov 				struct kmem_cache *cache, const void *object)
20334303244SAndrey Konovalov {
20434303244SAndrey Konovalov 	if (kasan_enabled())
20534303244SAndrey Konovalov 		return __kasan_init_slab_obj(cache, object);
20634303244SAndrey Konovalov 	return (void *)object;
20734303244SAndrey Konovalov }
20834303244SAndrey Konovalov 
209d57a964eSAndrey Konovalov bool __kasan_slab_free(struct kmem_cache *s, void *object,
210d57a964eSAndrey Konovalov 			unsigned long ip, bool init);
211d57a964eSAndrey Konovalov static __always_inline bool kasan_slab_free(struct kmem_cache *s,
212d57a964eSAndrey Konovalov 						void *object, bool init)
21334303244SAndrey Konovalov {
21434303244SAndrey Konovalov 	if (kasan_enabled())
215d57a964eSAndrey Konovalov 		return __kasan_slab_free(s, object, _RET_IP_, init);
21634303244SAndrey Konovalov 	return false;
21734303244SAndrey Konovalov }
21834303244SAndrey Konovalov 
219200072ceSAndrey Konovalov void __kasan_kfree_large(void *ptr, unsigned long ip);
220200072ceSAndrey Konovalov static __always_inline void kasan_kfree_large(void *ptr)
221200072ceSAndrey Konovalov {
222200072ceSAndrey Konovalov 	if (kasan_enabled())
223200072ceSAndrey Konovalov 		__kasan_kfree_large(ptr, _RET_IP_);
224200072ceSAndrey Konovalov }
225200072ceSAndrey Konovalov 
226eeb3160cSAndrey Konovalov void __kasan_slab_free_mempool(void *ptr, unsigned long ip);
227027b37b5SAndrey Konovalov static __always_inline void kasan_slab_free_mempool(void *ptr)
228eeb3160cSAndrey Konovalov {
229eeb3160cSAndrey Konovalov 	if (kasan_enabled())
230027b37b5SAndrey Konovalov 		__kasan_slab_free_mempool(ptr, _RET_IP_);
231eeb3160cSAndrey Konovalov }
232eeb3160cSAndrey Konovalov 
23334303244SAndrey Konovalov void * __must_check __kasan_slab_alloc(struct kmem_cache *s,
234da844b78SAndrey Konovalov 				       void *object, gfp_t flags, bool init);
23534303244SAndrey Konovalov static __always_inline void * __must_check kasan_slab_alloc(
236da844b78SAndrey Konovalov 		struct kmem_cache *s, void *object, gfp_t flags, bool init)
23734303244SAndrey Konovalov {
23834303244SAndrey Konovalov 	if (kasan_enabled())
239da844b78SAndrey Konovalov 		return __kasan_slab_alloc(s, object, flags, init);
24034303244SAndrey Konovalov 	return object;
24134303244SAndrey Konovalov }
24234303244SAndrey Konovalov 
24334303244SAndrey Konovalov void * __must_check __kasan_kmalloc(struct kmem_cache *s, const void *object,
24434303244SAndrey Konovalov 				    size_t size, gfp_t flags);
24534303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc(struct kmem_cache *s,
24634303244SAndrey Konovalov 				const void *object, size_t size, gfp_t flags)
24734303244SAndrey Konovalov {
24834303244SAndrey Konovalov 	if (kasan_enabled())
24934303244SAndrey Konovalov 		return __kasan_kmalloc(s, object, size, flags);
25034303244SAndrey Konovalov 	return (void *)object;
25134303244SAndrey Konovalov }
25234303244SAndrey Konovalov 
25334303244SAndrey Konovalov void * __must_check __kasan_kmalloc_large(const void *ptr,
25434303244SAndrey Konovalov 					  size_t size, gfp_t flags);
25534303244SAndrey Konovalov static __always_inline void * __must_check kasan_kmalloc_large(const void *ptr,
25634303244SAndrey Konovalov 						      size_t size, gfp_t flags)
25734303244SAndrey Konovalov {
25834303244SAndrey Konovalov 	if (kasan_enabled())
25934303244SAndrey Konovalov 		return __kasan_kmalloc_large(ptr, size, flags);
26034303244SAndrey Konovalov 	return (void *)ptr;
26134303244SAndrey Konovalov }
26234303244SAndrey Konovalov 
26334303244SAndrey Konovalov void * __must_check __kasan_krealloc(const void *object,
26434303244SAndrey Konovalov 				     size_t new_size, gfp_t flags);
26534303244SAndrey Konovalov static __always_inline void * __must_check kasan_krealloc(const void *object,
26634303244SAndrey Konovalov 						 size_t new_size, gfp_t flags)
26734303244SAndrey Konovalov {
26834303244SAndrey Konovalov 	if (kasan_enabled())
26934303244SAndrey Konovalov 		return __kasan_krealloc(object, new_size, flags);
27034303244SAndrey Konovalov 	return (void *)object;
27134303244SAndrey Konovalov }
27234303244SAndrey Konovalov 
273611806b4SAndrey Konovalov /*
274611806b4SAndrey Konovalov  * Unlike kasan_check_read/write(), kasan_check_byte() is performed even for
275611806b4SAndrey Konovalov  * the hardware tag-based mode that doesn't rely on compiler instrumentation.
276611806b4SAndrey Konovalov  */
277611806b4SAndrey Konovalov bool __kasan_check_byte(const void *addr, unsigned long ip);
278611806b4SAndrey Konovalov static __always_inline bool kasan_check_byte(const void *addr)
279611806b4SAndrey Konovalov {
280611806b4SAndrey Konovalov 	if (kasan_enabled())
281611806b4SAndrey Konovalov 		return __kasan_check_byte(addr, _RET_IP_);
282611806b4SAndrey Konovalov 	return true;
283611806b4SAndrey Konovalov }
284611806b4SAndrey Konovalov 
285611806b4SAndrey Konovalov 
286b0845ce5SMark Rutland bool kasan_save_enable_multi_shot(void);
287b0845ce5SMark Rutland void kasan_restore_multi_shot(bool enabled);
288b0845ce5SMark Rutland 
2890b24beccSAndrey Ryabinin #else /* CONFIG_KASAN */
2900b24beccSAndrey Ryabinin 
291e86f8b09SAndrey Konovalov static inline slab_flags_t kasan_never_merge(void)
292e86f8b09SAndrey Konovalov {
293e86f8b09SAndrey Konovalov 	return 0;
294e86f8b09SAndrey Konovalov }
295cebd0eb2SAndrey Konovalov static inline void kasan_unpoison_range(const void *address, size_t size) {}
2967a3b8353SPeter Collingbourne static inline void kasan_poison_pages(struct page *page, unsigned int order,
2977a3b8353SPeter Collingbourne 				      bool init) {}
2987a3b8353SPeter Collingbourne static inline void kasan_unpoison_pages(struct page *page, unsigned int order,
2997a3b8353SPeter Collingbourne 					bool init) {}
3007ed2f9e6SAlexander Potapenko static inline void kasan_cache_create(struct kmem_cache *cache,
301be4a7988SAlexey Dobriyan 				      unsigned int *size,
302d50112edSAlexey Dobriyan 				      slab_flags_t *flags) {}
30392850134SAndrey Konovalov static inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) {}
30434303244SAndrey Konovalov static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; }
3056e48a966SMatthew Wilcox (Oracle) static inline void kasan_poison_slab(struct slab *slab) {}
3060316bec2SAndrey Ryabinin static inline void kasan_unpoison_object_data(struct kmem_cache *cache,
3070316bec2SAndrey Ryabinin 					void *object) {}
3080316bec2SAndrey Ryabinin static inline void kasan_poison_object_data(struct kmem_cache *cache,
3090316bec2SAndrey Ryabinin 					void *object) {}
3100116523cSAndrey Konovalov static inline void *kasan_init_slab_obj(struct kmem_cache *cache,
3110116523cSAndrey Konovalov 				const void *object)
3120116523cSAndrey Konovalov {
3130116523cSAndrey Konovalov 	return (void *)object;
3140116523cSAndrey Konovalov }
315d57a964eSAndrey Konovalov static inline bool kasan_slab_free(struct kmem_cache *s, void *object, bool init)
3160116523cSAndrey Konovalov {
31734303244SAndrey Konovalov 	return false;
3180116523cSAndrey Konovalov }
319200072ceSAndrey Konovalov static inline void kasan_kfree_large(void *ptr) {}
320027b37b5SAndrey Konovalov static inline void kasan_slab_free_mempool(void *ptr) {}
32134303244SAndrey Konovalov static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object,
322da844b78SAndrey Konovalov 				   gfp_t flags, bool init)
32334303244SAndrey Konovalov {
32434303244SAndrey Konovalov 	return object;
32534303244SAndrey Konovalov }
3260116523cSAndrey Konovalov static inline void *kasan_kmalloc(struct kmem_cache *s, const void *object,
3270116523cSAndrey Konovalov 				size_t size, gfp_t flags)
3280116523cSAndrey Konovalov {
3290116523cSAndrey Konovalov 	return (void *)object;
3300116523cSAndrey Konovalov }
33134303244SAndrey Konovalov static inline void *kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags)
33234303244SAndrey Konovalov {
33334303244SAndrey Konovalov 	return (void *)ptr;
33434303244SAndrey Konovalov }
3350116523cSAndrey Konovalov static inline void *kasan_krealloc(const void *object, size_t new_size,
3360116523cSAndrey Konovalov 				 gfp_t flags)
3370116523cSAndrey Konovalov {
3380116523cSAndrey Konovalov 	return (void *)object;
3390116523cSAndrey Konovalov }
340611806b4SAndrey Konovalov static inline bool kasan_check_byte(const void *address)
341611806b4SAndrey Konovalov {
342611806b4SAndrey Konovalov 	return true;
343611806b4SAndrey Konovalov }
3449b75a867SAndrey Ryabinin 
3450b24beccSAndrey Ryabinin #endif /* CONFIG_KASAN */
3460b24beccSAndrey Ryabinin 
34702c58773SWalter Wu #if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK)
348d56a9ef8SAndrey Konovalov void kasan_unpoison_task_stack(struct task_struct *task);
349d56a9ef8SAndrey Konovalov #else
350d56a9ef8SAndrey Konovalov static inline void kasan_unpoison_task_stack(struct task_struct *task) {}
351d56a9ef8SAndrey Konovalov #endif
352d56a9ef8SAndrey Konovalov 
3532bd926b4SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC
3542bd926b4SAndrey Konovalov 
3552bd926b4SAndrey Konovalov void kasan_cache_shrink(struct kmem_cache *cache);
3562bd926b4SAndrey Konovalov void kasan_cache_shutdown(struct kmem_cache *cache);
35726e760c9SWalter Wu void kasan_record_aux_stack(void *ptr);
3587cb3007cSMarco Elver void kasan_record_aux_stack_noalloc(void *ptr);
3592bd926b4SAndrey Konovalov 
3602bd926b4SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC */
3612bd926b4SAndrey Konovalov 
3622bd926b4SAndrey Konovalov static inline void kasan_cache_shrink(struct kmem_cache *cache) {}
3632bd926b4SAndrey Konovalov static inline void kasan_cache_shutdown(struct kmem_cache *cache) {}
36426e760c9SWalter Wu static inline void kasan_record_aux_stack(void *ptr) {}
3657cb3007cSMarco Elver static inline void kasan_record_aux_stack_noalloc(void *ptr) {}
3662bd926b4SAndrey Konovalov 
3672bd926b4SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */
3682bd926b4SAndrey Konovalov 
3692e903b91SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
3703c9e3aa1SAndrey Konovalov 
371c0054c56SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr)
372c0054c56SAndrey Konovalov {
373c0054c56SAndrey Konovalov 	return (void *)arch_kasan_reset_tag(addr);
374c0054c56SAndrey Konovalov }
3753c9e3aa1SAndrey Konovalov 
37649c6631dSVincenzo Frascino /**
37749c6631dSVincenzo Frascino  * kasan_report - print a report about a bad memory access detected by KASAN
37849c6631dSVincenzo Frascino  * @addr: address of the bad access
37949c6631dSVincenzo Frascino  * @size: size of the bad access
38049c6631dSVincenzo Frascino  * @is_write: whether the bad access is a write or a read
38149c6631dSVincenzo Frascino  * @ip: instruction pointer for the accessibility check or the bad access itself
38249c6631dSVincenzo Frascino  */
3838cceeff4SWalter Wu bool kasan_report(unsigned long addr, size_t size,
38441eea9cdSAndrey Konovalov 		bool is_write, unsigned long ip);
38541eea9cdSAndrey Konovalov 
3862e903b91SAndrey Konovalov #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
3873c9e3aa1SAndrey Konovalov 
3883c9e3aa1SAndrey Konovalov static inline void *kasan_reset_tag(const void *addr)
3893c9e3aa1SAndrey Konovalov {
3903c9e3aa1SAndrey Konovalov 	return (void *)addr;
3913c9e3aa1SAndrey Konovalov }
3923c9e3aa1SAndrey Konovalov 
3932e903b91SAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS*/
3942e903b91SAndrey Konovalov 
3958f7b5054SVincenzo Frascino #ifdef CONFIG_KASAN_HW_TAGS
3968f7b5054SVincenzo Frascino 
3978f7b5054SVincenzo Frascino void kasan_report_async(void);
3988f7b5054SVincenzo Frascino 
3998f7b5054SVincenzo Frascino #endif /* CONFIG_KASAN_HW_TAGS */
4008f7b5054SVincenzo Frascino 
4012e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS
4022e903b91SAndrey Konovalov void __init kasan_init_sw_tags(void);
4032e903b91SAndrey Konovalov #else
4042e903b91SAndrey Konovalov static inline void kasan_init_sw_tags(void) { }
4052e903b91SAndrey Konovalov #endif
4062e903b91SAndrey Konovalov 
4072e903b91SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS
4082e903b91SAndrey Konovalov void kasan_init_hw_tags_cpu(void);
4092e903b91SAndrey Konovalov void __init kasan_init_hw_tags(void);
4102e903b91SAndrey Konovalov #else
4112e903b91SAndrey Konovalov static inline void kasan_init_hw_tags_cpu(void) { }
4122e903b91SAndrey Konovalov static inline void kasan_init_hw_tags(void) { }
4132e903b91SAndrey Konovalov #endif
414080eb83fSAndrey Konovalov 
4153c5c3cfbSDaniel Axtens #ifdef CONFIG_KASAN_VMALLOC
4163b1a4a86SAndrey Konovalov 
417d98c9e83SAndrey Ryabinin int kasan_populate_vmalloc(unsigned long addr, unsigned long size);
418d98c9e83SAndrey Ryabinin void kasan_poison_vmalloc(const void *start, unsigned long size);
419d98c9e83SAndrey Ryabinin void kasan_unpoison_vmalloc(const void *start, unsigned long size);
4203c5c3cfbSDaniel Axtens void kasan_release_vmalloc(unsigned long start, unsigned long end,
4213c5c3cfbSDaniel Axtens 			   unsigned long free_region_start,
4223c5c3cfbSDaniel Axtens 			   unsigned long free_region_end);
4233b1a4a86SAndrey Konovalov 
4243252b1d8SKefeng Wang void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
4253252b1d8SKefeng Wang 
4263b1a4a86SAndrey Konovalov #else /* CONFIG_KASAN_VMALLOC */
4273b1a4a86SAndrey Konovalov 
428d98c9e83SAndrey Ryabinin static inline int kasan_populate_vmalloc(unsigned long start,
429d98c9e83SAndrey Ryabinin 					unsigned long size)
4303c5c3cfbSDaniel Axtens {
4313c5c3cfbSDaniel Axtens 	return 0;
4323c5c3cfbSDaniel Axtens }
4333c5c3cfbSDaniel Axtens 
434d98c9e83SAndrey Ryabinin static inline void kasan_poison_vmalloc(const void *start, unsigned long size)
435d98c9e83SAndrey Ryabinin { }
436d98c9e83SAndrey Ryabinin static inline void kasan_unpoison_vmalloc(const void *start, unsigned long size)
437d98c9e83SAndrey Ryabinin { }
4383c5c3cfbSDaniel Axtens static inline void kasan_release_vmalloc(unsigned long start,
4393c5c3cfbSDaniel Axtens 					 unsigned long end,
4403c5c3cfbSDaniel Axtens 					 unsigned long free_region_start,
4413c5c3cfbSDaniel Axtens 					 unsigned long free_region_end) {}
4423b1a4a86SAndrey Konovalov 
4433252b1d8SKefeng Wang static inline void kasan_populate_early_vm_area_shadow(void *start,
4443252b1d8SKefeng Wang 						       unsigned long size)
4453252b1d8SKefeng Wang { }
4463252b1d8SKefeng Wang 
4473b1a4a86SAndrey Konovalov #endif /* CONFIG_KASAN_VMALLOC */
4483b1a4a86SAndrey Konovalov 
4490fea6e9aSAndrey Konovalov #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \
4500fea6e9aSAndrey Konovalov 		!defined(CONFIG_KASAN_VMALLOC)
4513b1a4a86SAndrey Konovalov 
4523b1a4a86SAndrey Konovalov /*
4533b1a4a86SAndrey Konovalov  * These functions provide a special case to support backing module
4543b1a4a86SAndrey Konovalov  * allocations with real shadow memory. With KASAN vmalloc, the special
4553b1a4a86SAndrey Konovalov  * case is unnecessary, as the work is handled in the generic case.
4563b1a4a86SAndrey Konovalov  */
45760115fa5SKefeng Wang int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask);
4583b1a4a86SAndrey Konovalov void kasan_free_shadow(const struct vm_struct *vm);
4593b1a4a86SAndrey Konovalov 
4600fea6e9aSAndrey Konovalov #else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
4613b1a4a86SAndrey Konovalov 
46260115fa5SKefeng Wang static inline int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask) { return 0; }
4633b1a4a86SAndrey Konovalov static inline void kasan_free_shadow(const struct vm_struct *vm) {}
4643b1a4a86SAndrey Konovalov 
4650fea6e9aSAndrey Konovalov #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
4663c5c3cfbSDaniel Axtens 
4672f004eeaSJann Horn #ifdef CONFIG_KASAN_INLINE
4682f004eeaSJann Horn void kasan_non_canonical_hook(unsigned long addr);
4692f004eeaSJann Horn #else /* CONFIG_KASAN_INLINE */
4702f004eeaSJann Horn static inline void kasan_non_canonical_hook(unsigned long addr) { }
4712f004eeaSJann Horn #endif /* CONFIG_KASAN_INLINE */
4722f004eeaSJann Horn 
4730b24beccSAndrey Ryabinin #endif /* LINUX_KASAN_H */
474