kasan.h 2.7 KB
Newer Older
1 2 3 4 5 6 7 8
#ifndef __MM_KASAN_KASAN_H
#define __MM_KASAN_KASAN_H

#include <linux/kasan.h>

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

9 10 11 12
#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) */
13
#define KASAN_GLOBAL_REDZONE    0xFA  /* redzone for global variable */
14

15 16 17 18 19 20 21 22 23
/*
 * 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

24 25 26 27
/* Don't break randconfig/all*config builds */
#ifndef KASAN_ABI_VERSION
#define KASAN_ABI_VERSION 1
#endif
28

29 30 31 32 33 34 35 36
struct kasan_access_info {
	const void *access_addr;
	const void *first_bad_addr;
	size_t access_size;
	bool is_write;
	unsigned long ip;
};

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
/* 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
};

A
Alexander Potapenko 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
/**
 * Structures to keep alloc and free tracks *
 */

enum kasan_state {
	KASAN_STATE_INIT,
	KASAN_STATE_ALLOC,
	KASAN_STATE_FREE
};

struct kasan_track {
	u64 cpu : 6;			/* for NR_CPUS = 64 */
	u64 pid : 16;			/* 65536 processes */
	u64 when : 42;			/* ~140 years */
};

struct kasan_alloc_meta {
	u32 state : 2;	/* enum kasan_state */
	u32 alloc_size : 30;
	struct kasan_track track;
};

struct kasan_free_meta {
	/* Allocator freelist pointer, unused by KASAN. */
	void **freelist;
	struct kasan_track track;
};

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


91 92 93 94 95 96
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);
}

97
static inline bool kasan_report_enabled(void)
98 99 100 101 102 103 104 105
{
	return !current->kasan_depth;
}

void kasan_report(unsigned long addr, size_t size,
		bool is_write, unsigned long ip);

#endif