xref: /openbmc/linux/mm/kasan/kasan.h (revision 93397d3a2f1bc67eeff6a6ca0c59e628d2169f41)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
20b24beccSAndrey Ryabinin #ifndef __MM_KASAN_KASAN_H
30b24beccSAndrey Ryabinin #define __MM_KASAN_KASAN_H
40b24beccSAndrey Ryabinin 
57bc0584eSAndrey Konovalov #include <linux/atomic.h>
60b24beccSAndrey Ryabinin #include <linux/kasan.h>
782868247SMark Rutland #include <linux/kasan-tags.h>
82b830526SAlexander Potapenko #include <linux/kfence.h>
9cd11016eSAlexander Potapenko #include <linux/stackdepot.h>
100b24beccSAndrey Ryabinin 
117ebfce33SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
128f7b5054SVincenzo Frascino 
138028caacSAndrey Konovalov #include <linux/static_key.h>
147ebfce33SAndrey Konovalov 
157ebfce33SAndrey Konovalov DECLARE_STATIC_KEY_TRUE(kasan_flag_stacktrace);
167ebfce33SAndrey Konovalov 
kasan_stack_collection_enabled(void)177ebfce33SAndrey Konovalov static inline bool kasan_stack_collection_enabled(void)
187ebfce33SAndrey Konovalov {
197ebfce33SAndrey Konovalov 	return static_branch_unlikely(&kasan_flag_stacktrace);
207ebfce33SAndrey Konovalov }
217ebfce33SAndrey Konovalov 
227ebfce33SAndrey Konovalov #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
237ebfce33SAndrey Konovalov 
kasan_stack_collection_enabled(void)247ebfce33SAndrey Konovalov static inline bool kasan_stack_collection_enabled(void)
257ebfce33SAndrey Konovalov {
267ebfce33SAndrey Konovalov 	return true;
277ebfce33SAndrey Konovalov }
287ebfce33SAndrey Konovalov 
297ebfce33SAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
307ebfce33SAndrey Konovalov 
317ebfce33SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS
327ebfce33SAndrey Konovalov 
3377a63c69SYee Lee #include "../slab.h"
348f7b5054SVincenzo Frascino 
35551b2bcbSAndrey Konovalov DECLARE_STATIC_KEY_TRUE(kasan_flag_vmalloc);
362d27e585SVincenzo Frascino 
372d27e585SVincenzo Frascino enum kasan_mode {
382d27e585SVincenzo Frascino 	KASAN_MODE_SYNC,
392d27e585SVincenzo Frascino 	KASAN_MODE_ASYNC,
402d27e585SVincenzo Frascino 	KASAN_MODE_ASYMM,
412d27e585SVincenzo Frascino };
422d27e585SVincenzo Frascino 
432d27e585SVincenzo Frascino extern enum kasan_mode kasan_mode __ro_after_init;
448f7b5054SVincenzo Frascino 
4544383cefSAndrey Konovalov extern unsigned long kasan_page_alloc_sample;
4644383cefSAndrey Konovalov extern unsigned int kasan_page_alloc_sample_order;
4744383cefSAndrey Konovalov DECLARE_PER_CPU(long, kasan_page_alloc_skip);
4844383cefSAndrey Konovalov 
kasan_vmalloc_enabled(void)49551b2bcbSAndrey Konovalov static inline bool kasan_vmalloc_enabled(void)
50551b2bcbSAndrey Konovalov {
51551b2bcbSAndrey Konovalov 	return static_branch_likely(&kasan_flag_vmalloc);
52551b2bcbSAndrey Konovalov }
53551b2bcbSAndrey Konovalov 
kasan_async_fault_possible(void)542d27e585SVincenzo Frascino static inline bool kasan_async_fault_possible(void)
558f7b5054SVincenzo Frascino {
562d27e585SVincenzo Frascino 	return kasan_mode == KASAN_MODE_ASYNC || kasan_mode == KASAN_MODE_ASYMM;
572d27e585SVincenzo Frascino }
582d27e585SVincenzo Frascino 
kasan_sync_fault_possible(void)592d27e585SVincenzo Frascino static inline bool kasan_sync_fault_possible(void)
602d27e585SVincenzo Frascino {
612d27e585SVincenzo Frascino 	return kasan_mode == KASAN_MODE_SYNC || kasan_mode == KASAN_MODE_ASYMM;
628f7b5054SVincenzo Frascino }
63fc0e5b91SAndrey Konovalov 
kasan_sample_page_alloc(unsigned int order)6444383cefSAndrey Konovalov static inline bool kasan_sample_page_alloc(unsigned int order)
6544383cefSAndrey Konovalov {
6644383cefSAndrey Konovalov 	/* Fast-path for when sampling is disabled. */
6744383cefSAndrey Konovalov 	if (kasan_page_alloc_sample == 1)
6844383cefSAndrey Konovalov 		return true;
6944383cefSAndrey Konovalov 
7044383cefSAndrey Konovalov 	if (order < kasan_page_alloc_sample_order)
7144383cefSAndrey Konovalov 		return true;
7244383cefSAndrey Konovalov 
7344383cefSAndrey Konovalov 	if (this_cpu_dec_return(kasan_page_alloc_skip) < 0) {
7444383cefSAndrey Konovalov 		this_cpu_write(kasan_page_alloc_skip,
7544383cefSAndrey Konovalov 			       kasan_page_alloc_sample - 1);
7644383cefSAndrey Konovalov 		return true;
7744383cefSAndrey Konovalov 	}
7844383cefSAndrey Konovalov 
7944383cefSAndrey Konovalov 	return false;
8044383cefSAndrey Konovalov }
8144383cefSAndrey Konovalov 
82284f8590SAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */
838f7b5054SVincenzo Frascino 
kasan_async_fault_possible(void)842d27e585SVincenzo Frascino static inline bool kasan_async_fault_possible(void)
858f7b5054SVincenzo Frascino {
868f7b5054SVincenzo Frascino 	return false;
878f7b5054SVincenzo Frascino }
888f7b5054SVincenzo Frascino 
kasan_sync_fault_possible(void)892d27e585SVincenzo Frascino static inline bool kasan_sync_fault_possible(void)
902d27e585SVincenzo Frascino {
912d27e585SVincenzo Frascino 	return true;
922d27e585SVincenzo Frascino }
932d27e585SVincenzo Frascino 
kasan_sample_page_alloc(unsigned int order)9444383cefSAndrey Konovalov static inline bool kasan_sample_page_alloc(unsigned int order)
9544383cefSAndrey Konovalov {
9644383cefSAndrey Konovalov 	return true;
9744383cefSAndrey Konovalov }
9844383cefSAndrey Konovalov 
99284f8590SAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */
100284f8590SAndrey Konovalov 
101284f8590SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC
102284f8590SAndrey Konovalov 
103284f8590SAndrey Konovalov /* Generic KASAN uses per-object metadata to store stack traces. */
kasan_requires_meta(void)104284f8590SAndrey Konovalov static inline bool kasan_requires_meta(void)
105284f8590SAndrey Konovalov {
106284f8590SAndrey Konovalov 	/*
107284f8590SAndrey Konovalov 	 * Technically, Generic KASAN always collects stack traces right now.
108284f8590SAndrey Konovalov 	 * However, let's use kasan_stack_collection_enabled() in case the
109284f8590SAndrey Konovalov 	 * kasan.stacktrace command-line argument is changed to affect
110284f8590SAndrey Konovalov 	 * Generic KASAN.
111284f8590SAndrey Konovalov 	 */
112284f8590SAndrey Konovalov 	return kasan_stack_collection_enabled();
113284f8590SAndrey Konovalov }
114284f8590SAndrey Konovalov 
115284f8590SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC */
116284f8590SAndrey Konovalov 
117284f8590SAndrey Konovalov /* Tag-based KASAN modes do not use per-object metadata. */
kasan_requires_meta(void)118284f8590SAndrey Konovalov static inline bool kasan_requires_meta(void)
119284f8590SAndrey Konovalov {
120284f8590SAndrey Konovalov 	return false;
121284f8590SAndrey Konovalov }
122284f8590SAndrey Konovalov 
123284f8590SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */
1248028caacSAndrey Konovalov 
1256c6a04feSAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
1261f600626SAndrey Konovalov #define KASAN_GRANULE_SIZE	(1UL << KASAN_SHADOW_SCALE_SHIFT)
1276c6a04feSAndrey Konovalov #else
1286c6a04feSAndrey Konovalov #include <asm/mte-kasan.h>
1296c6a04feSAndrey Konovalov #define KASAN_GRANULE_SIZE	MTE_GRANULE_SIZE
1306c6a04feSAndrey Konovalov #endif
1316c6a04feSAndrey Konovalov 
1321f600626SAndrey Konovalov #define KASAN_GRANULE_MASK	(KASAN_GRANULE_SIZE - 1)
1330b24beccSAndrey Ryabinin 
134affc3f07SAndrey Konovalov #define KASAN_MEMORY_PER_SHADOW_PAGE	(KASAN_GRANULE_SIZE << PAGE_SHIFT)
135affc3f07SAndrey Konovalov 
1367f94ffbcSAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC
13706bc4cf6SAndrey Konovalov #define KASAN_PAGE_FREE		0xFF  /* freed page */
138fc0e5b91SAndrey Konovalov #define KASAN_PAGE_REDZONE	0xFE  /* redzone for kmalloc_large allocation */
13906bc4cf6SAndrey Konovalov #define KASAN_SLAB_REDZONE	0xFC  /* redzone for slab object */
14006bc4cf6SAndrey Konovalov #define KASAN_SLAB_FREE		0xFB  /* freed slab object */
141fc0e5b91SAndrey Konovalov #define KASAN_VMALLOC_INVALID	0xF8  /* inaccessible space in vmap area */
1427f94ffbcSAndrey Konovalov #else
14306bc4cf6SAndrey Konovalov #define KASAN_PAGE_FREE		KASAN_TAG_INVALID
1447f94ffbcSAndrey Konovalov #define KASAN_PAGE_REDZONE	KASAN_TAG_INVALID
14506bc4cf6SAndrey Konovalov #define KASAN_SLAB_REDZONE	KASAN_TAG_INVALID
14606bc4cf6SAndrey Konovalov #define KASAN_SLAB_FREE		KASAN_TAG_INVALID
147fc0e5b91SAndrey Konovalov #define KASAN_VMALLOC_INVALID	KASAN_TAG_INVALID /* only used for SW_TAGS */
1487f94ffbcSAndrey Konovalov #endif
1497f94ffbcSAndrey Konovalov 
150fe1ac91eSAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC
151fe1ac91eSAndrey Konovalov 
15206bc4cf6SAndrey Konovalov #define KASAN_SLAB_FREETRACK	0xFA  /* freed slab object with free track */
153e4b7818bSWalter Wu #define KASAN_GLOBAL_REDZONE	0xF9  /* redzone for global variable */
1540316bec2SAndrey Ryabinin 
155fc0e5b91SAndrey Konovalov /* Stack redzone shadow values. Compiler ABI, do not change. */
156c420f167SAndrey Ryabinin #define KASAN_STACK_LEFT	0xF1
157c420f167SAndrey Ryabinin #define KASAN_STACK_MID		0xF2
158c420f167SAndrey Ryabinin #define KASAN_STACK_RIGHT	0xF3
159c420f167SAndrey Ryabinin #define KASAN_STACK_PARTIAL	0xF4
160c420f167SAndrey Ryabinin 
161fc0e5b91SAndrey Konovalov /* alloca redzone shadow values. */
162342061eeSPaul Lawrence #define KASAN_ALLOCA_LEFT	0xCA
163342061eeSPaul Lawrence #define KASAN_ALLOCA_RIGHT	0xCB
164342061eeSPaul Lawrence 
165fc0e5b91SAndrey Konovalov /* alloca redzone size. Compiler ABI, do not change. */
166342061eeSPaul Lawrence #define KASAN_ALLOCA_REDZONE_SIZE	32
167342061eeSPaul Lawrence 
168fc0e5b91SAndrey Konovalov /* Stack frame marker. Compiler ABI, do not change. */
169e8969219SMarco Elver #define KASAN_CURRENT_STACK_FRAME_MAGIC 0x41B58AB3
170e8969219SMarco Elver 
171fc0e5b91SAndrey Konovalov /* Dummy value to avoid breaking randconfig/all*config builds. */
172bebf56a1SAndrey Ryabinin #ifndef KASAN_ABI_VERSION
173bebf56a1SAndrey Ryabinin #define KASAN_ABI_VERSION 1
174bebf56a1SAndrey Ryabinin #endif
175b8c73fc2SAndrey Ryabinin 
176fe1ac91eSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */
177fe1ac91eSAndrey Konovalov 
17896e0279dSAndrey Konovalov /* Metadata layout customization. */
17996e0279dSAndrey Konovalov #define META_BYTES_PER_BLOCK 1
18096e0279dSAndrey Konovalov #define META_BLOCKS_PER_ROW 16
18196e0279dSAndrey Konovalov #define META_BYTES_PER_ROW (META_BLOCKS_PER_ROW * META_BYTES_PER_BLOCK)
18296e0279dSAndrey Konovalov #define META_MEM_BYTES_PER_ROW (META_BYTES_PER_ROW * KASAN_GRANULE_SIZE)
18396e0279dSAndrey Konovalov #define META_ROWS_AROUND_ADDR 2
18496e0279dSAndrey Konovalov 
18559e6e098SAndrey Konovalov #define KASAN_STACK_DEPTH 64
18659e6e098SAndrey Konovalov 
18759e6e098SAndrey Konovalov struct kasan_track {
18859e6e098SAndrey Konovalov 	u32 pid;
18959e6e098SAndrey Konovalov 	depot_stack_handle_t stack;
19059e6e098SAndrey Konovalov };
19159e6e098SAndrey Konovalov 
19231c65110SAndrey Konovalov enum kasan_report_type {
19331c65110SAndrey Konovalov 	KASAN_REPORT_ACCESS,
19431c65110SAndrey Konovalov 	KASAN_REPORT_INVALID_FREE,
1953de0de75SKuan-Ying Lee 	KASAN_REPORT_DOUBLE_FREE,
19631c65110SAndrey Konovalov };
19731c65110SAndrey Konovalov 
198c965cdd6SAndrey Konovalov struct kasan_report_info {
199015b109fSAndrey Konovalov 	/* Filled in by kasan_report_*(). */
20031c65110SAndrey Konovalov 	enum kasan_report_type type;
201bb6e04a1SArnd Bergmann 	const void *access_addr;
2020b24beccSAndrey Ryabinin 	size_t access_size;
2030b24beccSAndrey Ryabinin 	bool is_write;
2040b24beccSAndrey Ryabinin 	unsigned long ip;
205015b109fSAndrey Konovalov 
206015b109fSAndrey Konovalov 	/* Filled in by the common reporting code. */
207bb6e04a1SArnd Bergmann 	const void *first_bad_addr;
2087fae3dd0SAndrey Konovalov 	struct kmem_cache *cache;
2097fae3dd0SAndrey Konovalov 	void *object;
2108f17febbSKuan-Ying Lee 	size_t alloc_size;
21159e6e098SAndrey Konovalov 
21259e6e098SAndrey Konovalov 	/* Filled in by the mode-specific reporting code. */
21359e6e098SAndrey Konovalov 	const char *bug_type;
21459e6e098SAndrey Konovalov 	struct kasan_track alloc_track;
21559e6e098SAndrey Konovalov 	struct kasan_track free_track;
2160b24beccSAndrey Ryabinin };
2170b24beccSAndrey Ryabinin 
218fc0e5b91SAndrey Konovalov /* Do not change the struct layout: compiler ABI. */
219bebf56a1SAndrey Ryabinin struct kasan_source_location {
220bebf56a1SAndrey Ryabinin 	const char *filename;
221bebf56a1SAndrey Ryabinin 	int line_no;
222bebf56a1SAndrey Ryabinin 	int column_no;
223bebf56a1SAndrey Ryabinin };
224bebf56a1SAndrey Ryabinin 
225fc0e5b91SAndrey Konovalov /* Do not change the struct layout: compiler ABI. */
226bebf56a1SAndrey Ryabinin struct kasan_global {
227bebf56a1SAndrey Ryabinin 	const void *beg;		/* Address of the beginning of the global variable. */
228bebf56a1SAndrey Ryabinin 	size_t size;			/* Size of the global variable. */
229fc0e5b91SAndrey Konovalov 	size_t size_with_redzone;	/* Size of the variable + size of the redzone. 32 bytes aligned. */
230bebf56a1SAndrey Ryabinin 	const void *name;
231bebf56a1SAndrey Ryabinin 	const void *module_name;	/* Name of the module where the global variable is declared. */
232fc0e5b91SAndrey Konovalov 	unsigned long has_dynamic_init;	/* This is needed for C++. */
233bebf56a1SAndrey Ryabinin #if KASAN_ABI_VERSION >= 4
234bebf56a1SAndrey Ryabinin 	struct kasan_source_location *location;
235bebf56a1SAndrey Ryabinin #endif
236045d599aSDmitry Vyukov #if KASAN_ABI_VERSION >= 5
237045d599aSDmitry Vyukov 	char *odr_indicator;
238045d599aSDmitry Vyukov #endif
239bebf56a1SAndrey Ryabinin };
240bebf56a1SAndrey Ryabinin 
24159e6e098SAndrey Konovalov /* Structures for keeping alloc and free meta. */
2427ed2f9e6SAlexander Potapenko 
243be95e13fSAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC
244be95e13fSAndrey Konovalov 
2457ed2f9e6SAlexander Potapenko struct kasan_alloc_meta {
246b3cbd9bfSAndrey Ryabinin 	struct kasan_track alloc_track;
247be95e13fSAndrey Konovalov 	/* Free track is stored in kasan_free_meta. */
24826e760c9SWalter Wu 	depot_stack_handle_t aux_stack[2];
2497ed2f9e6SAlexander Potapenko };
2507ed2f9e6SAlexander Potapenko 
25155834c59SAlexander Potapenko struct qlist_node {
25255834c59SAlexander Potapenko 	struct qlist_node *next;
25355834c59SAlexander Potapenko };
25497593cadSAndrey Konovalov 
25597593cadSAndrey Konovalov /*
256fc0e5b91SAndrey Konovalov  * Free meta is stored either in the object itself or in the redzone after the
257fc0e5b91SAndrey Konovalov  * object. In the former case, free meta offset is 0. In the latter case, the
258fc0e5b91SAndrey Konovalov  * offset is between 0 and INT_MAX. INT_MAX marks that free meta is not present.
25997593cadSAndrey Konovalov  */
26097593cadSAndrey Konovalov #define KASAN_NO_FREE_META INT_MAX
26197593cadSAndrey Konovalov 
262fc0e5b91SAndrey Konovalov /*
263fc0e5b91SAndrey Konovalov  * Free meta is only used by Generic mode while the object is in quarantine.
264fc0e5b91SAndrey Konovalov  * After that, slab allocator stores the freelist pointer in the object.
265fc0e5b91SAndrey Konovalov  */
2667ed2f9e6SAlexander Potapenko struct kasan_free_meta {
26755834c59SAlexander Potapenko 	struct qlist_node quarantine_link;
268e4b7818bSWalter Wu 	struct kasan_track free_track;
2697ed2f9e6SAlexander Potapenko };
2707ed2f9e6SAlexander Potapenko 
271be95e13fSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */
272be95e13fSAndrey Konovalov 
2737bc0584eSAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
2747bc0584eSAndrey Konovalov 
2757bc0584eSAndrey Konovalov struct kasan_stack_ring_entry {
2767bc0584eSAndrey Konovalov 	void *ptr;
2777bc0584eSAndrey Konovalov 	size_t size;
2787bc0584eSAndrey Konovalov 	u32 pid;
2797bc0584eSAndrey Konovalov 	depot_stack_handle_t stack;
2807bc0584eSAndrey Konovalov 	bool is_free;
2817bc0584eSAndrey Konovalov };
2827bc0584eSAndrey Konovalov 
2837bc0584eSAndrey Konovalov struct kasan_stack_ring {
2847bc0584eSAndrey Konovalov 	rwlock_t lock;
28580b92bfeSAndrey Konovalov 	size_t size;
2867bc0584eSAndrey Konovalov 	atomic64_t pos;
28780b92bfeSAndrey Konovalov 	struct kasan_stack_ring_entry *entries;
2887bc0584eSAndrey Konovalov };
2897bc0584eSAndrey Konovalov 
2907bc0584eSAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
2917bc0584eSAndrey Konovalov 
2922e903b91SAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
2932e903b91SAndrey Konovalov 
294*2a86f1b5SHuacai Chen #ifndef kasan_shadow_to_mem
kasan_shadow_to_mem(const void * shadow_addr)2950b24beccSAndrey Ryabinin static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
2960b24beccSAndrey Ryabinin {
2970b24beccSAndrey Ryabinin 	return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
2980b24beccSAndrey Ryabinin 		<< KASAN_SHADOW_SCALE_SHIFT);
2990b24beccSAndrey Ryabinin }
3009b04c764SQing Zhang #endif
3010b24beccSAndrey Ryabinin 
302*2a86f1b5SHuacai Chen #ifndef addr_has_metadata
addr_has_metadata(const void * addr)3039701c9ffSArnd Bergmann static __always_inline bool addr_has_metadata(const void *addr)
30411cd3cd6SAndrey Konovalov {
3059d7b7dd9SAndrey Konovalov 	return (kasan_reset_tag(addr) >=
3069d7b7dd9SAndrey Konovalov 		kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
30711cd3cd6SAndrey Konovalov }
308*2a86f1b5SHuacai Chen #endif
30911cd3cd6SAndrey Konovalov 
310b5f6e0fcSMarco Elver /**
311f00748bfSAndrey Konovalov  * kasan_check_range - Check memory region, and report if invalid access.
312b5f6e0fcSMarco Elver  * @addr: the accessed address
313b5f6e0fcSMarco Elver  * @size: the accessed size
314b5f6e0fcSMarco Elver  * @write: true if access is a write access
315b5f6e0fcSMarco Elver  * @ret_ip: return address
316b5f6e0fcSMarco Elver  * @return: true if access was valid, false if invalid
317b5f6e0fcSMarco Elver  */
318bb6e04a1SArnd Bergmann bool kasan_check_range(const void *addr, size_t size, bool write,
319bffa986cSAndrey Konovalov 				unsigned long ret_ip);
320bffa986cSAndrey Konovalov 
3212e903b91SAndrey Konovalov #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
3222e903b91SAndrey Konovalov 
addr_has_metadata(const void * addr)3239701c9ffSArnd Bergmann static __always_inline bool addr_has_metadata(const void *addr)
3242e903b91SAndrey Konovalov {
325b99acdcbSVincenzo Frascino 	return (is_vmalloc_addr(addr) || virt_addr_valid(addr));
3262e903b91SAndrey Konovalov }
3272e903b91SAndrey Konovalov 
3282e903b91SAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
3292e903b91SAndrey Konovalov 
330bb6e04a1SArnd Bergmann const void *kasan_find_first_bad_addr(const void *addr, size_t size);
3318f17febbSKuan-Ying Lee size_t kasan_get_alloc_size(void *object, struct kmem_cache *cache);
33259e6e098SAndrey Konovalov void kasan_complete_mode_report_info(struct kasan_report_info *info);
33359e6e098SAndrey Konovalov void kasan_metadata_fetch_row(char *buffer, void *row);
33459e6e098SAndrey Konovalov 
335d8dd3971SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
336f00748bfSAndrey Konovalov void kasan_print_tags(u8 addr_tag, const void *addr);
337d8dd3971SAndrey Konovalov #else
kasan_print_tags(u8 addr_tag,const void * addr)338f00748bfSAndrey Konovalov static inline void kasan_print_tags(u8 addr_tag, const void *addr) { }
339d8dd3971SAndrey Konovalov #endif
340d8dd3971SAndrey Konovalov 
3411e0f611fSAndrey Konovalov #if defined(CONFIG_KASAN_STACK)
342f00748bfSAndrey Konovalov void kasan_print_address_stack_frame(const void *addr);
34397fc7122SAndrey Konovalov #else
kasan_print_address_stack_frame(const void * addr)344f00748bfSAndrey Konovalov static inline void kasan_print_address_stack_frame(const void *addr) { }
34597fc7122SAndrey Konovalov #endif
34697fc7122SAndrey Konovalov 
34788f29765SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC
34888f29765SAndrey Konovalov void kasan_print_aux_stacks(struct kmem_cache *cache, const void *object);
34988f29765SAndrey Konovalov #else
kasan_print_aux_stacks(struct kmem_cache * cache,const void * object)35088f29765SAndrey Konovalov static inline void kasan_print_aux_stacks(struct kmem_cache *cache, const void *object) { }
35188f29765SAndrey Konovalov #endif
35288f29765SAndrey Konovalov 
353bb6e04a1SArnd Bergmann bool kasan_report(const void *addr, size_t size,
3540b24beccSAndrey Ryabinin 		bool is_write, unsigned long ip);
3553de0de75SKuan-Ying Lee void kasan_report_invalid_free(void *object, unsigned long ip, enum kasan_report_type type);
3560b24beccSAndrey Ryabinin 
3576e48a966SMatthew Wilcox (Oracle) struct slab *kasan_addr_to_slab(const void *addr);
358ae8f06b3SWalter Wu 
3592f356801SAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC
3605935143dSAndrey Konovalov void kasan_init_cache_meta(struct kmem_cache *cache, unsigned int *size);
361284f8590SAndrey Konovalov void kasan_init_object_meta(struct kmem_cache *cache, const void *object);
3622f356801SAndrey Konovalov struct kasan_alloc_meta *kasan_get_alloc_meta(struct kmem_cache *cache,
3632f356801SAndrey Konovalov 						const void *object);
3642f356801SAndrey Konovalov struct kasan_free_meta *kasan_get_free_meta(struct kmem_cache *cache,
3652f356801SAndrey Konovalov 						const void *object);
366284f8590SAndrey Konovalov #else
kasan_init_cache_meta(struct kmem_cache * cache,unsigned int * size)3675935143dSAndrey Konovalov static inline void kasan_init_cache_meta(struct kmem_cache *cache, unsigned int *size) { }
kasan_init_object_meta(struct kmem_cache * cache,const void * object)368284f8590SAndrey Konovalov static inline void kasan_init_object_meta(struct kmem_cache *cache, const void *object) { }
3692f356801SAndrey Konovalov #endif
3702f356801SAndrey Konovalov 
3717594b347SMarco Elver depot_stack_handle_t kasan_save_stack(gfp_t flags, bool can_alloc);
372e4b7818bSWalter Wu void kasan_set_track(struct kasan_track *track, gfp_t flags);
373ccf643e6SAndrey Konovalov void kasan_save_alloc_info(struct kmem_cache *cache, void *object, gfp_t flags);
3746b074349SAndrey Konovalov void kasan_save_free_info(struct kmem_cache *cache, void *object);
37526e760c9SWalter Wu 
3762bd926b4SAndrey Konovalov #if defined(CONFIG_KASAN_GENERIC) && \
3772bd926b4SAndrey Konovalov 	(defined(CONFIG_SLAB) || defined(CONFIG_SLUB))
378f00748bfSAndrey Konovalov bool kasan_quarantine_put(struct kmem_cache *cache, void *object);
379f00748bfSAndrey Konovalov void kasan_quarantine_reduce(void);
380f00748bfSAndrey Konovalov void kasan_quarantine_remove_cache(struct kmem_cache *cache);
38155834c59SAlexander Potapenko #else
kasan_quarantine_put(struct kmem_cache * cache,void * object)382f00748bfSAndrey Konovalov static inline bool kasan_quarantine_put(struct kmem_cache *cache, void *object) { return false; }
kasan_quarantine_reduce(void)383f00748bfSAndrey Konovalov static inline void kasan_quarantine_reduce(void) { }
kasan_quarantine_remove_cache(struct kmem_cache * cache)384f00748bfSAndrey Konovalov static inline void kasan_quarantine_remove_cache(struct kmem_cache *cache) { }
38555834c59SAlexander Potapenko #endif
38655834c59SAlexander Potapenko 
3873c9e3aa1SAndrey Konovalov #ifndef arch_kasan_set_tag
arch_kasan_set_tag(const void * addr,u8 tag)388c412a769SQian Cai static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
389c412a769SQian Cai {
390c412a769SQian Cai 	return addr;
391c412a769SQian Cai }
3923c9e3aa1SAndrey Konovalov #endif
3933c9e3aa1SAndrey Konovalov #ifndef arch_kasan_get_tag
3943c9e3aa1SAndrey Konovalov #define arch_kasan_get_tag(addr)	0
3953c9e3aa1SAndrey Konovalov #endif
3963c9e3aa1SAndrey Konovalov 
3973c9e3aa1SAndrey Konovalov #define set_tag(addr, tag)	((void *)arch_kasan_set_tag((addr), (tag)))
3983c9e3aa1SAndrey Konovalov #define get_tag(addr)		arch_kasan_get_tag(addr)
3993c9e3aa1SAndrey Konovalov 
400ccbe2aabSAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS
401ccbe2aabSAndrey Konovalov 
4020eafff1cSAndrey Konovalov #define hw_enable_tag_checks_sync()		arch_enable_tag_checks_sync()
4030eafff1cSAndrey Konovalov #define hw_enable_tag_checks_async()		arch_enable_tag_checks_async()
4040eafff1cSAndrey Konovalov #define hw_enable_tag_checks_asymm()		arch_enable_tag_checks_asymm()
4050d3c9468SAndrey Konovalov #define hw_suppress_tag_checks_start()		arch_suppress_tag_checks_start()
4060d3c9468SAndrey Konovalov #define hw_suppress_tag_checks_stop()		arch_suppress_tag_checks_stop()
407e80a76aaSAndrey Konovalov #define hw_force_async_tag_fault()		arch_force_async_tag_fault()
408ccbe2aabSAndrey Konovalov #define hw_get_random_tag()			arch_get_random_tag()
409ccbe2aabSAndrey Konovalov #define hw_get_mem_tag(addr)			arch_get_mem_tag(addr)
410d9b6f907SAndrey Konovalov #define hw_set_mem_tag_range(addr, size, tag, init) \
411d9b6f907SAndrey Konovalov 			arch_set_mem_tag_range((addr), (size), (tag), (init))
412ccbe2aabSAndrey Konovalov 
4130eafff1cSAndrey Konovalov void kasan_enable_hw_tags(void);
414b1add418SVincenzo Frascino 
415f05842cfSAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */
416f05842cfSAndrey Konovalov 
kasan_enable_hw_tags(void)4170eafff1cSAndrey Konovalov static inline void kasan_enable_hw_tags(void) { }
418b1add418SVincenzo Frascino 
419ccbe2aabSAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */
420ccbe2aabSAndrey Konovalov 
4217ebfce33SAndrey Konovalov #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
4227ebfce33SAndrey Konovalov void __init kasan_init_tags(void);
4237ebfce33SAndrey Konovalov #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
4247ebfce33SAndrey Konovalov 
425f05842cfSAndrey Konovalov #if defined(CONFIG_KASAN_HW_TAGS) && IS_ENABLED(CONFIG_KASAN_KUNIT_TEST)
426f05842cfSAndrey Konovalov 
427e80a76aaSAndrey Konovalov void kasan_force_async_fault(void);
428f05842cfSAndrey Konovalov 
429b1add418SVincenzo Frascino #else /* CONFIG_KASAN_HW_TAGS && CONFIG_KASAN_KUNIT_TEST */
430f05842cfSAndrey Konovalov 
kasan_force_async_fault(void)431e80a76aaSAndrey Konovalov static inline void kasan_force_async_fault(void) { }
432f05842cfSAndrey Konovalov 
433b1add418SVincenzo Frascino #endif /* CONFIG_KASAN_HW_TAGS && CONFIG_KASAN_KUNIT_TEST */
434f05842cfSAndrey Konovalov 
435d8dd3971SAndrey Konovalov #ifdef CONFIG_KASAN_SW_TAGS
436f00748bfSAndrey Konovalov u8 kasan_random_tag(void);
437d8dd3971SAndrey Konovalov #elif defined(CONFIG_KASAN_HW_TAGS)
kasan_random_tag(void)438f00748bfSAndrey Konovalov static inline u8 kasan_random_tag(void) { return hw_get_random_tag(); }
439d8dd3971SAndrey Konovalov #else
kasan_random_tag(void)440f00748bfSAndrey Konovalov static inline u8 kasan_random_tag(void) { return 0; }
441d8dd3971SAndrey Konovalov #endif
442d8dd3971SAndrey Konovalov 
44357345fa6SAndrey Konovalov #ifdef CONFIG_KASAN_HW_TAGS
44457345fa6SAndrey Konovalov 
kasan_poison(const void * addr,size_t size,u8 value,bool init)445aa5c219cSAndrey Konovalov static inline void kasan_poison(const void *addr, size_t size, u8 value, bool init)
44657345fa6SAndrey Konovalov {
447cde8a7ebSAndrey Konovalov 	addr = kasan_reset_tag(addr);
4482b830526SAlexander Potapenko 
4492b830526SAlexander Potapenko 	/* Skip KFENCE memory if called explicitly outside of sl*b. */
450cde8a7ebSAndrey Konovalov 	if (is_kfence_address(addr))
4512b830526SAlexander Potapenko 		return;
4522b830526SAlexander Potapenko 
453cde8a7ebSAndrey Konovalov 	if (WARN_ON((unsigned long)addr & KASAN_GRANULE_MASK))
454cde8a7ebSAndrey Konovalov 		return;
455cde8a7ebSAndrey Konovalov 	if (WARN_ON(size & KASAN_GRANULE_MASK))
456cde8a7ebSAndrey Konovalov 		return;
457cde8a7ebSAndrey Konovalov 
458aa5c219cSAndrey Konovalov 	hw_set_mem_tag_range((void *)addr, size, value, init);
45957345fa6SAndrey Konovalov }
46057345fa6SAndrey Konovalov 
kasan_unpoison(const void * addr,size_t size,bool init)461aa5c219cSAndrey Konovalov static inline void kasan_unpoison(const void *addr, size_t size, bool init)
46257345fa6SAndrey Konovalov {
463cde8a7ebSAndrey Konovalov 	u8 tag = get_tag(addr);
4642b830526SAlexander Potapenko 
465cde8a7ebSAndrey Konovalov 	addr = kasan_reset_tag(addr);
4662b830526SAlexander Potapenko 
4672b830526SAlexander Potapenko 	/* Skip KFENCE memory if called explicitly outside of sl*b. */
468cde8a7ebSAndrey Konovalov 	if (is_kfence_address(addr))
4692b830526SAlexander Potapenko 		return;
4702b830526SAlexander Potapenko 
471cde8a7ebSAndrey Konovalov 	if (WARN_ON((unsigned long)addr & KASAN_GRANULE_MASK))
472cde8a7ebSAndrey Konovalov 		return;
473cde8a7ebSAndrey Konovalov 	size = round_up(size, KASAN_GRANULE_SIZE);
474cde8a7ebSAndrey Konovalov 
475aa5c219cSAndrey Konovalov 	hw_set_mem_tag_range((void *)addr, size, tag, init);
47657345fa6SAndrey Konovalov }
47757345fa6SAndrey Konovalov 
kasan_byte_accessible(const void * addr)478611806b4SAndrey Konovalov static inline bool kasan_byte_accessible(const void *addr)
47957345fa6SAndrey Konovalov {
48057345fa6SAndrey Konovalov 	u8 ptr_tag = get_tag(addr);
481611806b4SAndrey Konovalov 	u8 mem_tag = hw_get_mem_tag((void *)addr);
48257345fa6SAndrey Konovalov 
483bfcfe371SPeter Collingbourne 	return ptr_tag == KASAN_TAG_KERNEL || ptr_tag == mem_tag;
48457345fa6SAndrey Konovalov }
48557345fa6SAndrey Konovalov 
48657345fa6SAndrey Konovalov #else /* CONFIG_KASAN_HW_TAGS */
48757345fa6SAndrey Konovalov 
488e2db1a9aSAndrey Konovalov /**
489f0953a1bSIngo Molnar  * kasan_poison - mark the memory range as inaccessible
490e2db1a9aSAndrey Konovalov  * @addr - range start address, must be aligned to KASAN_GRANULE_SIZE
491cde8a7ebSAndrey Konovalov  * @size - range size, must be aligned to KASAN_GRANULE_SIZE
492e2db1a9aSAndrey Konovalov  * @value - value that's written to metadata for the range
493aa5c219cSAndrey Konovalov  * @init - whether to initialize the memory range (only for hardware tag-based)
494e2db1a9aSAndrey Konovalov  *
495e2db1a9aSAndrey Konovalov  * The size gets aligned to KASAN_GRANULE_SIZE before marking the range.
496e2db1a9aSAndrey Konovalov  */
497aa5c219cSAndrey Konovalov void kasan_poison(const void *addr, size_t size, u8 value, bool init);
498e2db1a9aSAndrey Konovalov 
499e2db1a9aSAndrey Konovalov /**
500e2db1a9aSAndrey Konovalov  * kasan_unpoison - mark the memory range as accessible
501e2db1a9aSAndrey Konovalov  * @addr - range start address, must be aligned to KASAN_GRANULE_SIZE
502cde8a7ebSAndrey Konovalov  * @size - range size, can be unaligned
503aa5c219cSAndrey Konovalov  * @init - whether to initialize the memory range (only for hardware tag-based)
504e2db1a9aSAndrey Konovalov  *
505e2db1a9aSAndrey Konovalov  * For the tag-based modes, the @size gets aligned to KASAN_GRANULE_SIZE before
506e2db1a9aSAndrey Konovalov  * marking the range.
507e2db1a9aSAndrey Konovalov  * For the generic mode, the last granule of the memory range gets partially
508e2db1a9aSAndrey Konovalov  * unpoisoned based on the @size.
509e2db1a9aSAndrey Konovalov  */
510aa5c219cSAndrey Konovalov void kasan_unpoison(const void *addr, size_t size, bool init);
511e2db1a9aSAndrey Konovalov 
512611806b4SAndrey Konovalov bool kasan_byte_accessible(const void *addr);
51357345fa6SAndrey Konovalov 
51457345fa6SAndrey Konovalov #endif /* CONFIG_KASAN_HW_TAGS */
51557345fa6SAndrey Konovalov 
516e2db1a9aSAndrey Konovalov #ifdef CONFIG_KASAN_GENERIC
517e2db1a9aSAndrey Konovalov 
518e2db1a9aSAndrey Konovalov /**
519e2db1a9aSAndrey Konovalov  * kasan_poison_last_granule - mark the last granule of the memory range as
520f0953a1bSIngo Molnar  * inaccessible
521e2db1a9aSAndrey Konovalov  * @addr - range start address, must be aligned to KASAN_GRANULE_SIZE
522e2db1a9aSAndrey Konovalov  * @size - range size
523e2db1a9aSAndrey Konovalov  *
524e2db1a9aSAndrey Konovalov  * This function is only available for the generic mode, as it's the only mode
525e2db1a9aSAndrey Konovalov  * that has partially poisoned memory granules.
526e2db1a9aSAndrey Konovalov  */
527e2db1a9aSAndrey Konovalov void kasan_poison_last_granule(const void *address, size_t size);
528e2db1a9aSAndrey Konovalov 
529e2db1a9aSAndrey Konovalov #else /* CONFIG_KASAN_GENERIC */
530e2db1a9aSAndrey Konovalov 
kasan_poison_last_granule(const void * address,size_t size)531e2db1a9aSAndrey Konovalov static inline void kasan_poison_last_granule(const void *address, size_t size) { }
532e2db1a9aSAndrey Konovalov 
533e2db1a9aSAndrey Konovalov #endif /* CONFIG_KASAN_GENERIC */
534e2db1a9aSAndrey Konovalov 
535af3751f3SDaniel Axtens #ifndef kasan_arch_is_ready
kasan_arch_is_ready(void)536af3751f3SDaniel Axtens static inline bool kasan_arch_is_ready(void)	{ return true; }
537af3751f3SDaniel Axtens #elif !defined(CONFIG_KASAN_GENERIC) || !defined(CONFIG_KASAN_OUTLINE)
538af3751f3SDaniel Axtens #error kasan_arch_is_ready only works in KASAN generic outline mode!
539af3751f3SDaniel Axtens #endif
540af3751f3SDaniel Axtens 
541c8c7016fSAndrey Konovalov #if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST)
542c8c7016fSAndrey Konovalov 
543c8c7016fSAndrey Konovalov void kasan_kunit_test_suite_start(void);
544c8c7016fSAndrey Konovalov void kasan_kunit_test_suite_end(void);
545c8c7016fSAndrey Konovalov 
546c8c7016fSAndrey Konovalov #else /* CONFIG_KASAN_KUNIT_TEST */
547c8c7016fSAndrey Konovalov 
kasan_kunit_test_suite_start(void)548c8c7016fSAndrey Konovalov static inline void kasan_kunit_test_suite_start(void) { }
kasan_kunit_test_suite_end(void)549c8c7016fSAndrey Konovalov static inline void kasan_kunit_test_suite_end(void) { }
550c8c7016fSAndrey Konovalov 
551c8c7016fSAndrey Konovalov #endif /* CONFIG_KASAN_KUNIT_TEST */
552c8c7016fSAndrey Konovalov 
55380207910SAndrey Konovalov #if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST) || IS_ENABLED(CONFIG_KASAN_MODULE_TEST)
55480207910SAndrey Konovalov 
55580207910SAndrey Konovalov bool kasan_save_enable_multi_shot(void);
55680207910SAndrey Konovalov void kasan_restore_multi_shot(bool enabled);
55780207910SAndrey Konovalov 
55880207910SAndrey Konovalov #endif
55980207910SAndrey Konovalov 
560d321599cSAlexander Potapenko /*
561d321599cSAlexander Potapenko  * Exported functions for interfaces called from assembly or from generated
562fc0e5b91SAndrey Konovalov  * code. Declared here to avoid warnings about missing declarations.
563d321599cSAlexander Potapenko  */
564fc0e5b91SAndrey Konovalov 
565d321599cSAlexander Potapenko asmlinkage void kasan_unpoison_task_stack_below(const void *watermark);
566bb6e04a1SArnd Bergmann void __asan_register_globals(void *globals, ssize_t size);
567bb6e04a1SArnd Bergmann void __asan_unregister_globals(void *globals, ssize_t size);
568d321599cSAlexander Potapenko void __asan_handle_no_return(void);
569bb6e04a1SArnd Bergmann void __asan_alloca_poison(void *, ssize_t size);
570bb6e04a1SArnd Bergmann void __asan_allocas_unpoison(void *stack_top, ssize_t stack_bottom);
571d321599cSAlexander Potapenko 
572bb6e04a1SArnd Bergmann void __asan_load1(void *);
573bb6e04a1SArnd Bergmann void __asan_store1(void *);
574bb6e04a1SArnd Bergmann void __asan_load2(void *);
575bb6e04a1SArnd Bergmann void __asan_store2(void *);
576bb6e04a1SArnd Bergmann void __asan_load4(void *);
577bb6e04a1SArnd Bergmann void __asan_store4(void *);
578bb6e04a1SArnd Bergmann void __asan_load8(void *);
579bb6e04a1SArnd Bergmann void __asan_store8(void *);
580bb6e04a1SArnd Bergmann void __asan_load16(void *);
581bb6e04a1SArnd Bergmann void __asan_store16(void *);
582bb6e04a1SArnd Bergmann void __asan_loadN(void *, ssize_t size);
583bb6e04a1SArnd Bergmann void __asan_storeN(void *, ssize_t size);
584d321599cSAlexander Potapenko 
585bb6e04a1SArnd Bergmann void __asan_load1_noabort(void *);
586bb6e04a1SArnd Bergmann void __asan_store1_noabort(void *);
587bb6e04a1SArnd Bergmann void __asan_load2_noabort(void *);
588bb6e04a1SArnd Bergmann void __asan_store2_noabort(void *);
589bb6e04a1SArnd Bergmann void __asan_load4_noabort(void *);
590bb6e04a1SArnd Bergmann void __asan_store4_noabort(void *);
591bb6e04a1SArnd Bergmann void __asan_load8_noabort(void *);
592bb6e04a1SArnd Bergmann void __asan_store8_noabort(void *);
593bb6e04a1SArnd Bergmann void __asan_load16_noabort(void *);
594bb6e04a1SArnd Bergmann void __asan_store16_noabort(void *);
595bb6e04a1SArnd Bergmann void __asan_loadN_noabort(void *, ssize_t size);
596bb6e04a1SArnd Bergmann void __asan_storeN_noabort(void *, ssize_t size);
59713cf0488SAndrey Konovalov 
598bb6e04a1SArnd Bergmann void __asan_report_load1_noabort(void *);
599bb6e04a1SArnd Bergmann void __asan_report_store1_noabort(void *);
600bb6e04a1SArnd Bergmann void __asan_report_load2_noabort(void *);
601bb6e04a1SArnd Bergmann void __asan_report_store2_noabort(void *);
602bb6e04a1SArnd Bergmann void __asan_report_load4_noabort(void *);
603bb6e04a1SArnd Bergmann void __asan_report_store4_noabort(void *);
604bb6e04a1SArnd Bergmann void __asan_report_load8_noabort(void *);
605bb6e04a1SArnd Bergmann void __asan_report_store8_noabort(void *);
606bb6e04a1SArnd Bergmann void __asan_report_load16_noabort(void *);
607bb6e04a1SArnd Bergmann void __asan_report_store16_noabort(void *);
608bb6e04a1SArnd Bergmann void __asan_report_load_n_noabort(void *, ssize_t size);
609bb6e04a1SArnd Bergmann void __asan_report_store_n_noabort(void *, ssize_t size);
610d321599cSAlexander Potapenko 
611bb6e04a1SArnd Bergmann void __asan_set_shadow_00(const void *addr, ssize_t size);
612bb6e04a1SArnd Bergmann void __asan_set_shadow_f1(const void *addr, ssize_t size);
613bb6e04a1SArnd Bergmann void __asan_set_shadow_f2(const void *addr, ssize_t size);
614bb6e04a1SArnd Bergmann void __asan_set_shadow_f3(const void *addr, ssize_t size);
615bb6e04a1SArnd Bergmann void __asan_set_shadow_f5(const void *addr, ssize_t size);
616bb6e04a1SArnd Bergmann void __asan_set_shadow_f8(const void *addr, ssize_t size);
617d321599cSAlexander Potapenko 
618bb6e04a1SArnd Bergmann void *__asan_memset(void *addr, int c, ssize_t len);
619bb6e04a1SArnd Bergmann void *__asan_memmove(void *dest, const void *src, ssize_t len);
620bb6e04a1SArnd Bergmann void *__asan_memcpy(void *dest, const void *src, ssize_t len);
62169d4c0d3SPeter Zijlstra 
622bb6e04a1SArnd Bergmann void __hwasan_load1_noabort(void *);
623bb6e04a1SArnd Bergmann void __hwasan_store1_noabort(void *);
624bb6e04a1SArnd Bergmann void __hwasan_load2_noabort(void *);
625bb6e04a1SArnd Bergmann void __hwasan_store2_noabort(void *);
626bb6e04a1SArnd Bergmann void __hwasan_load4_noabort(void *);
627bb6e04a1SArnd Bergmann void __hwasan_store4_noabort(void *);
628bb6e04a1SArnd Bergmann void __hwasan_load8_noabort(void *);
629bb6e04a1SArnd Bergmann void __hwasan_store8_noabort(void *);
630bb6e04a1SArnd Bergmann void __hwasan_load16_noabort(void *);
631bb6e04a1SArnd Bergmann void __hwasan_store16_noabort(void *);
632bb6e04a1SArnd Bergmann void __hwasan_loadN_noabort(void *, ssize_t size);
633bb6e04a1SArnd Bergmann void __hwasan_storeN_noabort(void *, ssize_t size);
63413cf0488SAndrey Konovalov 
635bb6e04a1SArnd Bergmann void __hwasan_tag_memory(void *, u8 tag, ssize_t size);
63613cf0488SAndrey Konovalov 
637bb6e04a1SArnd Bergmann void *__hwasan_memset(void *addr, int c, ssize_t len);
638bb6e04a1SArnd Bergmann void *__hwasan_memmove(void *dest, const void *src, ssize_t len);
639bb6e04a1SArnd Bergmann void *__hwasan_memcpy(void *dest, const void *src, ssize_t len);
64051287dcbSMarco Elver 
641bb6e04a1SArnd Bergmann void kasan_tag_mismatch(void *addr, unsigned long access_info,
642fb646a4cSArnd Bergmann 			unsigned long ret_ip);
643fb646a4cSArnd Bergmann 
644fc0e5b91SAndrey Konovalov #endif /* __MM_KASAN_KASAN_H */
645