kasan.h 12.8 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 11 12 13 14 15 16 17 18 19 20 21 22 23
#ifdef CONFIG_KASAN_HW_TAGS
#include <linux/static_key.h>
DECLARE_STATIC_KEY_FALSE(kasan_flag_stacktrace);
static inline bool kasan_stack_collection_enabled(void)
{
	return static_branch_unlikely(&kasan_flag_stacktrace);
}
#else
static inline bool kasan_stack_collection_enabled(void)
{
	return true;
}
#endif

extern bool kasan_flag_panic __ro_after_init;

24
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
25
#define KASAN_GRANULE_SIZE	(1UL << KASAN_SHADOW_SCALE_SHIFT)
26 27 28 29 30
#else
#include <asm/mte-kasan.h>
#define KASAN_GRANULE_SIZE	MTE_GRANULE_SIZE
#endif

31
#define KASAN_GRANULE_MASK	(KASAN_GRANULE_SIZE - 1)
32

33 34
#define KASAN_MEMORY_PER_SHADOW_PAGE	(KASAN_GRANULE_SIZE << PAGE_SHIFT)

35 36 37 38
#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 */

39
#ifdef CONFIG_KASAN_GENERIC
40 41 42 43
#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) */
44
#define KASAN_KMALLOC_FREETRACK 0xFA  /* object was freed and has free track set */
45 46 47 48 49
#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
50
#define KASAN_KMALLOC_FREETRACK KASAN_TAG_INVALID
51 52
#endif

53 54
#define KASAN_GLOBAL_REDZONE    0xF9  /* redzone for global variable */
#define KASAN_VMALLOC_INVALID   0xF8  /* unallocated space in vmapped page */
55

56 57 58 59 60 61 62 63 64
/*
 * 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

65 66 67 68 69 70 71 72
/*
 * alloca redzone shadow values
 */
#define KASAN_ALLOCA_LEFT	0xCA
#define KASAN_ALLOCA_RIGHT	0xCB

#define KASAN_ALLOCA_REDZONE_SIZE	32

73 74 75 76 77
/*
 * Stack frame marker (compiler ABI).
 */
#define KASAN_CURRENT_STACK_FRAME_MAGIC 0x41B58AB3

78 79 80 81
/* Don't break randconfig/all*config builds */
#ifndef KASAN_ABI_VERSION
#define KASAN_ABI_VERSION 1
#endif
82

83 84 85 86 87 88 89
/* Metadata layout customization. */
#define META_BYTES_PER_BLOCK 1
#define META_BLOCKS_PER_ROW 16
#define META_BYTES_PER_ROW (META_BLOCKS_PER_ROW * META_BYTES_PER_BLOCK)
#define META_MEM_BYTES_PER_ROW (META_BYTES_PER_ROW * KASAN_GRANULE_SIZE)
#define META_ROWS_AROUND_ADDR 2

90 91 92 93 94 95 96 97
struct kasan_access_info {
	const void *access_addr;
	const void *first_bad_addr;
	size_t access_size;
	bool is_write;
	unsigned long ip;
};

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
/* 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
116 117 118
#if KASAN_ABI_VERSION >= 5
	char *odr_indicator;
#endif
119 120
};

A
Alexander Potapenko 已提交
121 122 123 124
/**
 * Structures to keep alloc and free tracks *
 */

125 126
#define KASAN_STACK_DEPTH 64

A
Alexander Potapenko 已提交
127
struct kasan_track {
128 129
	u32 pid;
	depot_stack_handle_t stack;
A
Alexander Potapenko 已提交
130 131
};

132 133 134 135 136 137
#ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY
#define KASAN_NR_FREE_STACKS 5
#else
#define KASAN_NR_FREE_STACKS 1
#endif

A
Alexander Potapenko 已提交
138
struct kasan_alloc_meta {
139
	struct kasan_track alloc_track;
140 141 142 143 144 145
#ifdef CONFIG_KASAN_GENERIC
	/*
	 * call_rcu() call stack is stored into struct kasan_alloc_meta.
	 * The free stack is stored into struct kasan_free_meta.
	 */
	depot_stack_handle_t aux_stack[2];
146
#else
147
	struct kasan_track free_track[KASAN_NR_FREE_STACKS];
148
#endif
149 150 151 152
#ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY
	u8 free_pointer_tag[KASAN_NR_FREE_STACKS];
	u8 free_track_idx;
#endif
A
Alexander Potapenko 已提交
153 154
};

155 156 157
struct qlist_node {
	struct qlist_node *next;
};
158 159 160 161 162 163 164 165 166

/*
 * Generic mode either stores free meta in the object itself or in the redzone
 * after the object. In the former case free meta offset is 0, in the latter
 * case it has some sane value smaller than INT_MAX. Use INT_MAX as free meta
 * offset when free meta isn't present.
 */
#define KASAN_NO_FREE_META INT_MAX

A
Alexander Potapenko 已提交
167
struct kasan_free_meta {
168
#ifdef CONFIG_KASAN_GENERIC
169 170 171 172
	/* 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;
173 174
	struct kasan_track free_track;
#endif
A
Alexander Potapenko 已提交
175 176
};

177 178
struct kasan_alloc_meta *kasan_get_alloc_meta(struct kmem_cache *cache,
						const void *object);
179
#ifdef CONFIG_KASAN_GENERIC
180 181
struct kasan_free_meta *kasan_get_free_meta(struct kmem_cache *cache,
						const void *object);
182
#endif
A
Alexander Potapenko 已提交
183

184 185
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)

186 187 188 189 190 191
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);
}

192
static inline bool addr_has_metadata(const void *addr)
193 194 195 196
{
	return (addr >= kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
}

197 198 199 200 201 202 203 204 205
/**
 * check_memory_region - Check memory region, and report if invalid access.
 * @addr: the accessed address
 * @size: the accessed size
 * @write: true if access is a write access
 * @ret_ip: return address
 * @return: true if access was valid, false if invalid
 */
bool check_memory_region(unsigned long addr, size_t size, bool write,
206 207
				unsigned long ret_ip);

208 209 210 211
#else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */

static inline bool addr_has_metadata(const void *addr)
{
212
	return (is_vmalloc_addr(addr) || virt_addr_valid(addr));
213 214 215 216
}

#endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */

217 218 219 220 221 222
#if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
void print_tags(u8 addr_tag, const void *addr);
#else
static inline void print_tags(u8 addr_tag, const void *addr) { }
#endif

223
void *find_first_bad_addr(void *addr, size_t size);
224
const char *get_bug_type(struct kasan_access_info *info);
225
void metadata_fetch_row(char *buffer, void *row);
226

227 228 229 230 231 232
#if defined(CONFIG_KASAN_GENERIC) && CONFIG_KASAN_STACK
void print_address_stack_frame(const void *addr);
#else
static inline void print_address_stack_frame(const void *addr) { }
#endif

233
bool kasan_report(unsigned long addr, size_t size,
234
		bool is_write, unsigned long ip);
235
void kasan_report_invalid_free(void *object, unsigned long ip);
236

237 238
struct page *kasan_addr_to_page(const void *addr);

239
depot_stack_handle_t kasan_save_stack(gfp_t flags);
240 241 242 243
void kasan_set_track(struct kasan_track *track, gfp_t flags);
void kasan_set_free_info(struct kmem_cache *cache, void *object, u8 tag);
struct kasan_track *kasan_get_free_track(struct kmem_cache *cache,
				void *object, u8 tag);
244

245 246
#if defined(CONFIG_KASAN_GENERIC) && \
	(defined(CONFIG_SLAB) || defined(CONFIG_SLUB))
247
bool quarantine_put(struct kmem_cache *cache, void *object);
248 249 250
void quarantine_reduce(void);
void quarantine_remove_cache(struct kmem_cache *cache);
#else
251
static inline bool quarantine_put(struct kmem_cache *cache, void *object) { return false; }
252 253 254 255
static inline void quarantine_reduce(void) { }
static inline void quarantine_remove_cache(struct kmem_cache *cache) { }
#endif

256
#ifndef arch_kasan_set_tag
257 258 259 260
static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
{
	return addr;
}
261 262 263 264 265 266 267 268
#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 get_tag(addr)		arch_kasan_get_tag(addr)

269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
#ifdef CONFIG_KASAN_HW_TAGS

#ifndef arch_enable_tagging
#define arch_enable_tagging()
#endif
#ifndef arch_init_tags
#define arch_init_tags(max_tag)
#endif
#ifndef arch_get_random_tag
#define arch_get_random_tag()	(0xFF)
#endif
#ifndef arch_get_mem_tag
#define arch_get_mem_tag(addr)	(0xFF)
#endif
#ifndef arch_set_mem_tag_range
#define arch_set_mem_tag_range(addr, size, tag) ((void *)(addr))
#endif

#define hw_enable_tagging()			arch_enable_tagging()
#define hw_init_tags(max_tag)			arch_init_tags(max_tag)
#define hw_get_random_tag()			arch_get_random_tag()
#define hw_get_mem_tag(addr)			arch_get_mem_tag(addr)
#define hw_set_mem_tag_range(addr, size, tag)	arch_set_mem_tag_range((addr), (size), (tag))

#endif /* CONFIG_KASAN_HW_TAGS */

295 296 297 298 299 300 301 302
#ifdef CONFIG_KASAN_SW_TAGS
u8 random_tag(void);
#elif defined(CONFIG_KASAN_HW_TAGS)
static inline u8 random_tag(void) { return hw_get_random_tag(); }
#else
static inline u8 random_tag(void) { return 0; }
#endif

303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
#ifdef CONFIG_KASAN_HW_TAGS

static inline void poison_range(const void *address, size_t size, u8 value)
{
	hw_set_mem_tag_range(kasan_reset_tag(address),
			round_up(size, KASAN_GRANULE_SIZE), value);
}

static inline void unpoison_range(const void *address, size_t size)
{
	hw_set_mem_tag_range(kasan_reset_tag(address),
			round_up(size, KASAN_GRANULE_SIZE), get_tag(address));
}

static inline bool check_invalid_free(void *addr)
{
	u8 ptr_tag = get_tag(addr);
	u8 mem_tag = hw_get_mem_tag(addr);

	return (mem_tag == KASAN_TAG_INVALID) ||
		(ptr_tag != KASAN_TAG_KERNEL && ptr_tag != mem_tag);
}

#else /* CONFIG_KASAN_HW_TAGS */

void poison_range(const void *address, size_t size, u8 value);
void unpoison_range(const void *address, size_t size);
bool check_invalid_free(void *addr);

#endif /* CONFIG_KASAN_HW_TAGS */

334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
/*
 * 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_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);
355 356
void __asan_loadN(unsigned long addr, size_t size);
void __asan_storeN(unsigned long addr, size_t size);
357 358 359 360 361 362 363 364 365 366 367

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);
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
void __asan_loadN_noabort(unsigned long addr, size_t size);
void __asan_storeN_noabort(unsigned long addr, size_t size);

void __asan_report_load1_noabort(unsigned long addr);
void __asan_report_store1_noabort(unsigned long addr);
void __asan_report_load2_noabort(unsigned long addr);
void __asan_report_store2_noabort(unsigned long addr);
void __asan_report_load4_noabort(unsigned long addr);
void __asan_report_store4_noabort(unsigned long addr);
void __asan_report_load8_noabort(unsigned long addr);
void __asan_report_store8_noabort(unsigned long addr);
void __asan_report_load16_noabort(unsigned long addr);
void __asan_report_store16_noabort(unsigned long addr);
void __asan_report_load_n_noabort(unsigned long addr, size_t size);
void __asan_report_store_n_noabort(unsigned long addr, size_t size);
383 384 385 386 387 388 389 390

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);

391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
void __hwasan_load1_noabort(unsigned long addr);
void __hwasan_store1_noabort(unsigned long addr);
void __hwasan_load2_noabort(unsigned long addr);
void __hwasan_store2_noabort(unsigned long addr);
void __hwasan_load4_noabort(unsigned long addr);
void __hwasan_store4_noabort(unsigned long addr);
void __hwasan_load8_noabort(unsigned long addr);
void __hwasan_store8_noabort(unsigned long addr);
void __hwasan_load16_noabort(unsigned long addr);
void __hwasan_store16_noabort(unsigned long addr);
void __hwasan_loadN_noabort(unsigned long addr, size_t size);
void __hwasan_storeN_noabort(unsigned long addr, size_t size);

void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size);

406
#endif