Blame view

mm/kasan/kasan.h 7.38 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  /* SPDX-License-Identifier: GPL-2.0 */
0b24becc8   Andrey Ryabinin   kasan: add kernel...
2
3
4
5
  #ifndef __MM_KASAN_KASAN_H
  #define __MM_KASAN_KASAN_H
  
  #include <linux/kasan.h>
cd11016e5   Alexander Potapenko   mm, kasan: stackd...
6
  #include <linux/stackdepot.h>
0b24becc8   Andrey Ryabinin   kasan: add kernel...
7
8
9
  
  #define KASAN_SHADOW_SCALE_SIZE (1UL << KASAN_SHADOW_SCALE_SHIFT)
  #define KASAN_SHADOW_MASK       (KASAN_SHADOW_SCALE_SIZE - 1)
3c9e3aa11   Andrey Konovalov   kasan: add tag re...
10
11
12
  #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 */
7f94ffbc4   Andrey Konovalov   kasan: add hooks ...
13
  #ifdef CONFIG_KASAN_GENERIC
b8c73fc24   Andrey Ryabinin   mm: page_alloc: a...
14
  #define KASAN_FREE_PAGE         0xFF  /* page was freed */
0316bec22   Andrey Ryabinin   mm: slub: add ker...
15
16
17
  #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) */
7f94ffbc4   Andrey Konovalov   kasan: add hooks ...
18
19
20
21
22
23
  #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
bebf56a1b   Andrey Ryabinin   kasan: enable ins...
24
  #define KASAN_GLOBAL_REDZONE    0xFA  /* redzone for global variable */
0316bec22   Andrey Ryabinin   mm: slub: add ker...
25

c420f167d   Andrey Ryabinin   kasan: enable sta...
26
27
28
29
30
31
32
33
  /*
   * 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
342061ee4   Paul Lawrence   kasan: support al...
34
35
36
37
38
39
40
  /*
   * alloca redzone shadow values
   */
  #define KASAN_ALLOCA_LEFT	0xCA
  #define KASAN_ALLOCA_RIGHT	0xCB
  
  #define KASAN_ALLOCA_REDZONE_SIZE	32
e89692190   Marco Elver   mm/kasan: print f...
41
42
43
44
  /*
   * Stack frame marker (compiler ABI).
   */
  #define KASAN_CURRENT_STACK_FRAME_MAGIC 0x41B58AB3
bebf56a1b   Andrey Ryabinin   kasan: enable ins...
45
46
47
48
  /* Don't break randconfig/all*config builds */
  #ifndef KASAN_ABI_VERSION
  #define KASAN_ABI_VERSION 1
  #endif
b8c73fc24   Andrey Ryabinin   mm: page_alloc: a...
49

0b24becc8   Andrey Ryabinin   kasan: add kernel...
50
51
52
53
54
55
56
  struct kasan_access_info {
  	const void *access_addr;
  	const void *first_bad_addr;
  	size_t access_size;
  	bool is_write;
  	unsigned long ip;
  };
bebf56a1b   Andrey Ryabinin   kasan: enable ins...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  /* 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
045d599a2   Dmitry Vyukov   kasan: update kas...
75
76
77
  #if KASAN_ABI_VERSION >= 5
  	char *odr_indicator;
  #endif
bebf56a1b   Andrey Ryabinin   kasan: enable ins...
78
  };
7ed2f9e66   Alexander Potapenko   mm, kasan: SLAB s...
79
80
81
  /**
   * Structures to keep alloc and free tracks *
   */
cd11016e5   Alexander Potapenko   mm, kasan: stackd...
82
  #define KASAN_STACK_DEPTH 64
7ed2f9e66   Alexander Potapenko   mm, kasan: SLAB s...
83
  struct kasan_track {
cd11016e5   Alexander Potapenko   mm, kasan: stackd...
84
85
  	u32 pid;
  	depot_stack_handle_t stack;
7ed2f9e66   Alexander Potapenko   mm, kasan: SLAB s...
86
  };
ae8f06b31   Walter Wu   kasan: add memory...
87
88
89
90
91
  #ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY
  #define KASAN_NR_FREE_STACKS 5
  #else
  #define KASAN_NR_FREE_STACKS 1
  #endif
7ed2f9e66   Alexander Potapenko   mm, kasan: SLAB s...
92
  struct kasan_alloc_meta {
b3cbd9bf7   Andrey Ryabinin   mm/kasan: get rid...
93
  	struct kasan_track alloc_track;
ae8f06b31   Walter Wu   kasan: add memory...
94
95
96
97
98
  	struct kasan_track free_track[KASAN_NR_FREE_STACKS];
  #ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY
  	u8 free_pointer_tag[KASAN_NR_FREE_STACKS];
  	u8 free_track_idx;
  #endif
7ed2f9e66   Alexander Potapenko   mm, kasan: SLAB s...
99
  };
55834c590   Alexander Potapenko   mm: kasan: initia...
100
101
102
  struct qlist_node {
  	struct qlist_node *next;
  };
7ed2f9e66   Alexander Potapenko   mm, kasan: SLAB s...
103
  struct kasan_free_meta {
55834c590   Alexander Potapenko   mm: kasan: initia...
104
105
106
107
  	/* 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;
7ed2f9e66   Alexander Potapenko   mm, kasan: SLAB s...
108
109
110
111
112
113
  };
  
  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);
0b24becc8   Andrey Ryabinin   kasan: add kernel...
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);
  }
11cd3cd69   Andrey Konovalov   kasan: split out ...
119
120
121
122
  static inline bool addr_has_shadow(const void *addr)
  {
  	return (addr >= kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
  }
bffa986c6   Andrey Konovalov   kasan: move commo...
123
  void kasan_poison_shadow(const void *address, size_t size, u8 value);
b5f6e0fc7   Marco Elver   mm/kasan: change ...
124
125
126
127
128
129
130
131
132
  /**
   * 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,
bffa986c6   Andrey Konovalov   kasan: move commo...
133
  				unsigned long ret_ip);
121e8f81d   Andrey Konovalov   kasan: add bug re...
134
  void *find_first_bad_addr(void *addr, size_t size);
11cd3cd69   Andrey Konovalov   kasan: split out ...
135
  const char *get_bug_type(struct kasan_access_info *info);
0b24becc8   Andrey Ryabinin   kasan: add kernel...
136
137
  void kasan_report(unsigned long addr, size_t size,
  		bool is_write, unsigned long ip);
ee3ce779b   Dmitry Vyukov   kasan: don't use ...
138
  void kasan_report_invalid_free(void *object, unsigned long ip);
0b24becc8   Andrey Ryabinin   kasan: add kernel...
139

ae8f06b31   Walter Wu   kasan: add memory...
140
  struct page *kasan_addr_to_page(const void *addr);
2bd926b43   Andrey Konovalov   kasan: add CONFIG...
141
142
  #if defined(CONFIG_KASAN_GENERIC) && \
  	(defined(CONFIG_SLAB) || defined(CONFIG_SLUB))
55834c590   Alexander Potapenko   mm: kasan: initia...
143
144
145
146
147
148
149
150
151
  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
3c9e3aa11   Andrey Konovalov   kasan: add tag re...
152
  #ifdef CONFIG_KASAN_SW_TAGS
121e8f81d   Andrey Konovalov   kasan: add bug re...
153
  void print_tags(u8 addr_tag, const void *addr);
3c9e3aa11   Andrey Konovalov   kasan: add tag re...
154
155
156
  u8 random_tag(void);
  
  #else
121e8f81d   Andrey Konovalov   kasan: add bug re...
157
  static inline void print_tags(u8 addr_tag, const void *addr) { }
3c9e3aa11   Andrey Konovalov   kasan: add tag re...
158
159
160
161
162
163
164
165
  static inline u8 random_tag(void)
  {
  	return 0;
  }
  
  #endif
  
  #ifndef arch_kasan_set_tag
c412a769d   Qian Cai   kasan: fix variab...
166
167
168
169
  static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
  {
  	return addr;
  }
3c9e3aa11   Andrey Konovalov   kasan: add tag re...
170
171
172
173
174
175
176
177
178
179
180
  #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)
d321599cf   Alexander Potapenko   kasan: add functi...
181
182
183
184
185
186
187
188
189
190
  /*
   * 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);
d321599cf   Alexander Potapenko   kasan: add functi...
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
  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);
0b24becc8   Andrey Ryabinin   kasan: add kernel...
222
  #endif