kasan.h 6.7 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0 */
2 3 4 5
#ifndef __MM_KASAN_KASAN_H
#define __MM_KASAN_KASAN_H

#include <linux/kasan.h>
6
#include <linux/stackdepot.h>
7 8 9 10

#define KASAN_SHADOW_SCALE_SIZE (1UL << KASAN_SHADOW_SCALE_SHIFT)
#define KASAN_SHADOW_MASK       (KASAN_SHADOW_SCALE_SIZE - 1)

11 12 13 14
#define KASAN_TAG_KERNEL	0xFF /* native kernel pointers tag */
#define KASAN_TAG_INVALID	0xFE /* inaccessible memory tag */
#define KASAN_TAG_MAX		0xFD /* maximum value for random tags */

15
#ifdef CONFIG_KASAN_GENERIC
16 17 18 19
#define KASAN_FREE_PAGE         0xFF  /* page was freed */
#define KASAN_PAGE_REDZONE      0xFE  /* redzone for kmalloc_large allocations */
#define KASAN_KMALLOC_REDZONE   0xFC  /* redzone inside slub object */
#define KASAN_KMALLOC_FREE      0xFB  /* object was freed (kmem_cache_free/kfree) */
20 21 22 23 24 25 26
#else
#define KASAN_FREE_PAGE         KASAN_TAG_INVALID
#define KASAN_PAGE_REDZONE      KASAN_TAG_INVALID
#define KASAN_KMALLOC_REDZONE   KASAN_TAG_INVALID
#define KASAN_KMALLOC_FREE      KASAN_TAG_INVALID
#endif

27
#define KASAN_GLOBAL_REDZONE    0xFA  /* redzone for global variable */
28

29 30 31 32 33 34 35 36 37
/*
 * Stack redzone shadow values
 * (Those are compiler's ABI, don't change them)
 */
#define KASAN_STACK_LEFT        0xF1
#define KASAN_STACK_MID         0xF2
#define KASAN_STACK_RIGHT       0xF3
#define KASAN_STACK_PARTIAL     0xF4

38 39 40 41 42 43 44 45
/*
 * alloca redzone shadow values
 */
#define KASAN_ALLOCA_LEFT	0xCA
#define KASAN_ALLOCA_RIGHT	0xCB

#define KASAN_ALLOCA_REDZONE_SIZE	32

46 47 48 49
/* Don't break randconfig/all*config builds */
#ifndef KASAN_ABI_VERSION
#define KASAN_ABI_VERSION 1
#endif
50

51 52 53 54 55 56 57 58
struct kasan_access_info {
	const void *access_addr;
	const void *first_bad_addr;
	size_t access_size;
	bool is_write;
	unsigned long ip;
};

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
/* The layout of struct dictated by compiler */
struct kasan_source_location {
	const char *filename;
	int line_no;
	int column_no;
};

/* The layout of struct dictated by compiler */
struct kasan_global {
	const void *beg;		/* Address of the beginning of the global variable. */
	size_t size;			/* Size of the global variable. */
	size_t size_with_redzone;	/* Size of the variable + size of the red zone. 32 bytes aligned */
	const void *name;
	const void *module_name;	/* Name of the module where the global variable is declared. */
	unsigned long has_dynamic_init;	/* This needed for C++ */
#if KASAN_ABI_VERSION >= 4
	struct kasan_source_location *location;
#endif
77 78 79
#if KASAN_ABI_VERSION >= 5
	char *odr_indicator;
#endif
80 81
};

A
Alexander Potapenko 已提交
82 83 84 85
/**
 * Structures to keep alloc and free tracks *
 */

86 87
#define KASAN_STACK_DEPTH 64

A
Alexander Potapenko 已提交
88
struct kasan_track {
89 90
	u32 pid;
	depot_stack_handle_t stack;
A
Alexander Potapenko 已提交
91 92 93
};

struct kasan_alloc_meta {
94 95
	struct kasan_track alloc_track;
	struct kasan_track free_track;
A
Alexander Potapenko 已提交
96 97
};

98 99 100
struct qlist_node {
	struct qlist_node *next;
};
A
Alexander Potapenko 已提交
101
struct kasan_free_meta {
102 103 104 105
	/* This field is used while the object is in the quarantine.
	 * Otherwise it might be used for the allocator freelist.
	 */
	struct qlist_node quarantine_link;
A
Alexander Potapenko 已提交
106 107 108 109 110 111 112
};

struct kasan_alloc_meta *get_alloc_info(struct kmem_cache *cache,
					const void *object);
struct kasan_free_meta *get_free_info(struct kmem_cache *cache,
					const void *object);

113 114 115 116 117 118
static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
{
	return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
		<< KASAN_SHADOW_SCALE_SHIFT);
}

119 120 121 122 123
static inline bool addr_has_shadow(const void *addr)
{
	return (addr >= kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
}

124 125 126 127 128
void kasan_poison_shadow(const void *address, size_t size, u8 value);

void check_memory_region(unsigned long addr, size_t size, bool write,
				unsigned long ret_ip);

129
void *find_first_bad_addr(void *addr, size_t size);
130 131
const char *get_bug_type(struct kasan_access_info *info);

132 133
void kasan_report(unsigned long addr, size_t size,
		bool is_write, unsigned long ip);
134
void kasan_report_invalid_free(void *object, unsigned long ip);
135

136 137
#if defined(CONFIG_KASAN_GENERIC) && \
	(defined(CONFIG_SLAB) || defined(CONFIG_SLUB))
138 139 140 141 142 143 144 145 146 147
void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache);
void quarantine_reduce(void);
void quarantine_remove_cache(struct kmem_cache *cache);
#else
static inline void quarantine_put(struct kasan_free_meta *info,
				struct kmem_cache *cache) { }
static inline void quarantine_reduce(void) { }
static inline void quarantine_remove_cache(struct kmem_cache *cache) { }
#endif

148 149
#ifdef CONFIG_KASAN_SW_TAGS

150 151
void print_tags(u8 addr_tag, const void *addr);

152 153 154 155
u8 random_tag(void);

#else

156 157
static inline void print_tags(u8 addr_tag, const void *addr) { }

158 159 160 161 162 163 164 165
static inline u8 random_tag(void)
{
	return 0;
}

#endif

#ifndef arch_kasan_set_tag
166 167 168 169
static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
{
	return addr;
}
170 171 172 173 174 175 176 177 178 179 180 181
#endif
#ifndef arch_kasan_reset_tag
#define arch_kasan_reset_tag(addr)	((void *)(addr))
#endif
#ifndef arch_kasan_get_tag
#define arch_kasan_get_tag(addr)	0
#endif

#define set_tag(addr, tag)	((void *)arch_kasan_set_tag((addr), (tag)))
#define reset_tag(addr)		((void *)arch_kasan_reset_tag(addr))
#define get_tag(addr)		arch_kasan_get_tag(addr)

182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
/*
 * Exported functions for interfaces called from assembly or from generated
 * code. Declarations here to avoid warning about missing declarations.
 */
asmlinkage void kasan_unpoison_task_stack_below(const void *watermark);
void __asan_register_globals(struct kasan_global *globals, size_t size);
void __asan_unregister_globals(struct kasan_global *globals, size_t size);
void __asan_loadN(unsigned long addr, size_t size);
void __asan_storeN(unsigned long addr, size_t size);
void __asan_handle_no_return(void);
void __asan_alloca_poison(unsigned long addr, size_t size);
void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom);

void __asan_load1(unsigned long addr);
void __asan_store1(unsigned long addr);
void __asan_load2(unsigned long addr);
void __asan_store2(unsigned long addr);
void __asan_load4(unsigned long addr);
void __asan_store4(unsigned long addr);
void __asan_load8(unsigned long addr);
void __asan_store8(unsigned long addr);
void __asan_load16(unsigned long addr);
void __asan_store16(unsigned long addr);

void __asan_load1_noabort(unsigned long addr);
void __asan_store1_noabort(unsigned long addr);
void __asan_load2_noabort(unsigned long addr);
void __asan_store2_noabort(unsigned long addr);
void __asan_load4_noabort(unsigned long addr);
void __asan_store4_noabort(unsigned long addr);
void __asan_load8_noabort(unsigned long addr);
void __asan_store8_noabort(unsigned long addr);
void __asan_load16_noabort(unsigned long addr);
void __asan_store16_noabort(unsigned long addr);

void __asan_set_shadow_00(const void *addr, size_t size);
void __asan_set_shadow_f1(const void *addr, size_t size);
void __asan_set_shadow_f2(const void *addr, size_t size);
void __asan_set_shadow_f3(const void *addr, size_t size);
void __asan_set_shadow_f5(const void *addr, size_t size);
void __asan_set_shadow_f8(const void *addr, size_t size);

224
#endif