Blame view
lib/test_kasan.c
19.5 KB
d2912cb15 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
3f15801cd lib: add kasan te... |
2 3 4 5 |
/* * * Copyright (c) 2014 Samsung Electronics Co., Ltd. * Author: Andrey Ryabinin <a.ryabinin@samsung.com> |
3f15801cd lib: add kasan te... |
6 |
*/ |
19a33ca6c lib/test_kasan: a... |
7 |
#include <linux/bitops.h> |
0386bf385 kasan: add memcg ... |
8 |
#include <linux/delay.h> |
19a33ca6c lib/test_kasan: a... |
9 |
#include <linux/kasan.h> |
3f15801cd lib: add kasan te... |
10 |
#include <linux/kernel.h> |
eae08dcab kasan/tests: add ... |
11 |
#include <linux/mm.h> |
19a33ca6c lib/test_kasan: a... |
12 13 |
#include <linux/mman.h> #include <linux/module.h> |
3f15801cd lib: add kasan te... |
14 15 16 |
#include <linux/printk.h> #include <linux/slab.h> #include <linux/string.h> |
eae08dcab kasan/tests: add ... |
17 |
#include <linux/uaccess.h> |
b92a953cb lib/test_kasan.c:... |
18 |
#include <linux/io.h> |
065139169 kasan: add test f... |
19 |
#include <linux/vmalloc.h> |
b92a953cb lib/test_kasan.c:... |
20 21 |
#include <asm/page.h> |
3f15801cd lib: add kasan te... |
22 |
|
83c4e7a03 KUnit: KASAN Inte... |
23 |
#include <kunit/test.h> |
f33a01492 lib/test_kasan.c:... |
24 25 26 |
#include "../mm/kasan/kasan.h" #define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_SHADOW_SCALE_SIZE) |
828347f8f kasan: support us... |
27 |
/* |
adb72ae19 kasan: stop tests... |
28 29 30 |
* We assign some test results to these globals to make sure the tests * are not eliminated as dead code. */ |
adb72ae19 kasan: stop tests... |
31 |
void *kasan_ptr_result; |
83c4e7a03 KUnit: KASAN Inte... |
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
int kasan_int_result; static struct kunit_resource resource; static struct kunit_kasan_expectation fail_data; static bool multishot; static int kasan_test_init(struct kunit *test) { /* * Temporarily enable multi-shot mode and set panic_on_warn=0. * Otherwise, we'd only get a report for the first case. */ multishot = kasan_save_enable_multi_shot(); return 0; } static void kasan_test_exit(struct kunit *test) { kasan_restore_multi_shot(multishot); } /** * KUNIT_EXPECT_KASAN_FAIL() - Causes a test failure when the expression does * not cause a KASAN error. This uses a KUnit resource named "kasan_data." Do * Do not use this name for a KUnit resource outside here. * */ #define KUNIT_EXPECT_KASAN_FAIL(test, condition) do { \ fail_data.report_expected = true; \ fail_data.report_found = false; \ kunit_add_named_resource(test, \ NULL, \ NULL, \ &resource, \ "kasan_data", &fail_data); \ condition; \ KUNIT_EXPECT_EQ(test, \ fail_data.report_expected, \ fail_data.report_found); \ } while (0) |
73228c7ec KASAN: port KASAN... |
73 |
static void kmalloc_oob_right(struct kunit *test) |
3f15801cd lib: add kasan te... |
74 75 76 |
{ char *ptr; size_t size = 123; |
3f15801cd lib: add kasan te... |
77 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
78 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
f33a01492 lib/test_kasan.c:... |
79 |
|
73228c7ec KASAN: port KASAN... |
80 |
KUNIT_EXPECT_KASAN_FAIL(test, ptr[size + OOB_TAG_OFF] = 'x'); |
3f15801cd lib: add kasan te... |
81 82 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
83 |
static void kmalloc_oob_left(struct kunit *test) |
3f15801cd lib: add kasan te... |
84 85 86 |
{ char *ptr; size_t size = 15; |
3f15801cd lib: add kasan te... |
87 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
88 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
3f15801cd lib: add kasan te... |
89 |
|
73228c7ec KASAN: port KASAN... |
90 |
KUNIT_EXPECT_KASAN_FAIL(test, *ptr = *(ptr - 1)); |
3f15801cd lib: add kasan te... |
91 92 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
93 |
static void kmalloc_node_oob_right(struct kunit *test) |
3f15801cd lib: add kasan te... |
94 95 96 |
{ char *ptr; size_t size = 4096; |
3f15801cd lib: add kasan te... |
97 |
ptr = kmalloc_node(size, GFP_KERNEL, 0); |
73228c7ec KASAN: port KASAN... |
98 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
3f15801cd lib: add kasan te... |
99 |
|
73228c7ec KASAN: port KASAN... |
100 |
KUNIT_EXPECT_KASAN_FAIL(test, ptr[size] = 0); |
3f15801cd lib: add kasan te... |
101 102 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
103 |
static void kmalloc_pagealloc_oob_right(struct kunit *test) |
3f15801cd lib: add kasan te... |
104 105 106 |
{ char *ptr; size_t size = KMALLOC_MAX_CACHE_SIZE + 10; |
73228c7ec KASAN: port KASAN... |
107 108 109 110 |
if (!IS_ENABLED(CONFIG_SLUB)) { kunit_info(test, "CONFIG_SLUB is not enabled."); return; } |
e6e8379c8 kasan: modify kma... |
111 112 113 |
/* Allocate a chunk that does not fit into a SLUB cache to trigger * the page allocator fallback. */ |
e6e8379c8 kasan: modify kma... |
114 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
115 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
f33a01492 lib/test_kasan.c:... |
116 |
|
73228c7ec KASAN: port KASAN... |
117 |
KUNIT_EXPECT_KASAN_FAIL(test, ptr[size + OOB_TAG_OFF] = 0); |
e6e8379c8 kasan: modify kma... |
118 119 |
kfree(ptr); } |
47adccce3 kasan: detect inv... |
120 |
|
73228c7ec KASAN: port KASAN... |
121 |
static void kmalloc_pagealloc_uaf(struct kunit *test) |
47adccce3 kasan: detect inv... |
122 123 124 |
{ char *ptr; size_t size = KMALLOC_MAX_CACHE_SIZE + 10; |
73228c7ec KASAN: port KASAN... |
125 126 |
if (!IS_ENABLED(CONFIG_SLUB)) { kunit_info(test, "CONFIG_SLUB is not enabled."); |
47adccce3 kasan: detect inv... |
127 128 |
return; } |
73228c7ec KASAN: port KASAN... |
129 130 |
ptr = kmalloc(size, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
47adccce3 kasan: detect inv... |
131 |
kfree(ptr); |
73228c7ec KASAN: port KASAN... |
132 |
KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] = 0); |
47adccce3 kasan: detect inv... |
133 |
} |
73228c7ec KASAN: port KASAN... |
134 |
static void kmalloc_pagealloc_invalid_free(struct kunit *test) |
47adccce3 kasan: detect inv... |
135 136 137 |
{ char *ptr; size_t size = KMALLOC_MAX_CACHE_SIZE + 10; |
73228c7ec KASAN: port KASAN... |
138 139 |
if (!IS_ENABLED(CONFIG_SLUB)) { kunit_info(test, "CONFIG_SLUB is not enabled."); |
47adccce3 kasan: detect inv... |
140 141 |
return; } |
73228c7ec KASAN: port KASAN... |
142 143 144 145 |
ptr = kmalloc(size, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); KUNIT_EXPECT_KASAN_FAIL(test, kfree(ptr + 1)); |
47adccce3 kasan: detect inv... |
146 |
} |
e6e8379c8 kasan: modify kma... |
147 |
|
73228c7ec KASAN: port KASAN... |
148 |
static void kmalloc_large_oob_right(struct kunit *test) |
e6e8379c8 kasan: modify kma... |
149 150 151 152 153 154 |
{ char *ptr; size_t size = KMALLOC_MAX_CACHE_SIZE - 256; /* Allocate a chunk that is large enough, but still fits into a slab * and does not trigger the page allocator fallback in SLUB. */ |
3f15801cd lib: add kasan te... |
155 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
156 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
3f15801cd lib: add kasan te... |
157 |
|
73228c7ec KASAN: port KASAN... |
158 |
KUNIT_EXPECT_KASAN_FAIL(test, ptr[size] = 0); |
3f15801cd lib: add kasan te... |
159 160 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
161 |
static void kmalloc_oob_krealloc_more(struct kunit *test) |
3f15801cd lib: add kasan te... |
162 163 164 165 |
{ char *ptr1, *ptr2; size_t size1 = 17; size_t size2 = 19; |
3f15801cd lib: add kasan te... |
166 |
ptr1 = kmalloc(size1, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
167 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1); |
3f15801cd lib: add kasan te... |
168 |
|
73228c7ec KASAN: port KASAN... |
169 170 |
ptr2 = krealloc(ptr1, size2, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2); |
f33a01492 lib/test_kasan.c:... |
171 |
|
73228c7ec KASAN: port KASAN... |
172 |
KUNIT_EXPECT_KASAN_FAIL(test, ptr2[size2 + OOB_TAG_OFF] = 'x'); |
3f15801cd lib: add kasan te... |
173 174 |
kfree(ptr2); } |
73228c7ec KASAN: port KASAN... |
175 |
static void kmalloc_oob_krealloc_less(struct kunit *test) |
3f15801cd lib: add kasan te... |
176 177 178 179 |
{ char *ptr1, *ptr2; size_t size1 = 17; size_t size2 = 15; |
3f15801cd lib: add kasan te... |
180 |
ptr1 = kmalloc(size1, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
181 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1); |
f33a01492 lib/test_kasan.c:... |
182 |
|
73228c7ec KASAN: port KASAN... |
183 184 |
ptr2 = krealloc(ptr1, size2, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2); |
f33a01492 lib/test_kasan.c:... |
185 |
|
73228c7ec KASAN: port KASAN... |
186 |
KUNIT_EXPECT_KASAN_FAIL(test, ptr2[size2 + OOB_TAG_OFF] = 'x'); |
3f15801cd lib: add kasan te... |
187 188 |
kfree(ptr2); } |
73228c7ec KASAN: port KASAN... |
189 |
static void kmalloc_oob_16(struct kunit *test) |
3f15801cd lib: add kasan te... |
190 191 192 193 |
{ struct { u64 words[2]; } *ptr1, *ptr2; |
58b999d7a kasan: adopt KUNI... |
194 195 196 197 198 199 |
/* This test is specifically crafted for the generic mode. */ if (!IS_ENABLED(CONFIG_KASAN_GENERIC)) { kunit_info(test, "CONFIG_KASAN_GENERIC required "); return; } |
3f15801cd lib: add kasan te... |
200 |
ptr1 = kmalloc(sizeof(*ptr1) - 3, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
201 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1); |
3f15801cd lib: add kasan te... |
202 |
ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
203 204 205 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2); KUNIT_EXPECT_KASAN_FAIL(test, *ptr1 = *ptr2); |
3f15801cd lib: add kasan te... |
206 207 208 |
kfree(ptr1); kfree(ptr2); } |
58b999d7a kasan: adopt KUNI... |
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
static void kmalloc_uaf_16(struct kunit *test) { struct { u64 words[2]; } *ptr1, *ptr2; ptr1 = kmalloc(sizeof(*ptr1), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1); ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2); kfree(ptr2); KUNIT_EXPECT_KASAN_FAIL(test, *ptr1 = *ptr2); kfree(ptr1); } |
73228c7ec KASAN: port KASAN... |
225 |
static void kmalloc_oob_memset_2(struct kunit *test) |
f523e737c lib: test_kasan: ... |
226 227 228 |
{ char *ptr; size_t size = 8; |
f523e737c lib: test_kasan: ... |
229 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
230 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
f33a01492 lib/test_kasan.c:... |
231 |
|
73228c7ec KASAN: port KASAN... |
232 |
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + 7 + OOB_TAG_OFF, 0, 2)); |
f523e737c lib: test_kasan: ... |
233 234 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
235 |
static void kmalloc_oob_memset_4(struct kunit *test) |
f523e737c lib: test_kasan: ... |
236 237 238 |
{ char *ptr; size_t size = 8; |
f523e737c lib: test_kasan: ... |
239 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
240 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
f33a01492 lib/test_kasan.c:... |
241 |
|
73228c7ec KASAN: port KASAN... |
242 |
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + 5 + OOB_TAG_OFF, 0, 4)); |
f523e737c lib: test_kasan: ... |
243 244 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
245 |
static void kmalloc_oob_memset_8(struct kunit *test) |
f523e737c lib: test_kasan: ... |
246 247 248 |
{ char *ptr; size_t size = 8; |
f523e737c lib: test_kasan: ... |
249 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
250 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
f33a01492 lib/test_kasan.c:... |
251 |
|
73228c7ec KASAN: port KASAN... |
252 |
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + 1 + OOB_TAG_OFF, 0, 8)); |
f523e737c lib: test_kasan: ... |
253 254 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
255 |
static void kmalloc_oob_memset_16(struct kunit *test) |
f523e737c lib: test_kasan: ... |
256 257 258 |
{ char *ptr; size_t size = 16; |
f523e737c lib: test_kasan: ... |
259 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
260 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
f33a01492 lib/test_kasan.c:... |
261 |
|
73228c7ec KASAN: port KASAN... |
262 |
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + 1 + OOB_TAG_OFF, 0, 16)); |
f523e737c lib: test_kasan: ... |
263 264 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
265 |
static void kmalloc_oob_in_memset(struct kunit *test) |
3f15801cd lib: add kasan te... |
266 267 268 |
{ char *ptr; size_t size = 666; |
3f15801cd lib: add kasan te... |
269 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
270 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
f33a01492 lib/test_kasan.c:... |
271 |
|
73228c7ec KASAN: port KASAN... |
272 |
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr, 0, size + 5 + OOB_TAG_OFF)); |
3f15801cd lib: add kasan te... |
273 274 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
275 |
static void kmalloc_memmove_invalid_size(struct kunit *test) |
98f3b56fa kasan: add test f... |
276 277 278 279 |
{ char *ptr; size_t size = 64; volatile size_t invalid_size = -2; |
98f3b56fa kasan: add test f... |
280 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
281 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
98f3b56fa kasan: add test f... |
282 283 |
memset((char *)ptr, 0, 64); |
73228c7ec KASAN: port KASAN... |
284 285 286 |
KUNIT_EXPECT_KASAN_FAIL(test, memmove((char *)ptr, (char *)ptr + 4, invalid_size)); |
98f3b56fa kasan: add test f... |
287 288 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
289 |
static void kmalloc_uaf(struct kunit *test) |
3f15801cd lib: add kasan te... |
290 291 292 |
{ char *ptr; size_t size = 10; |
3f15801cd lib: add kasan te... |
293 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
294 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
3f15801cd lib: add kasan te... |
295 296 |
kfree(ptr); |
73228c7ec KASAN: port KASAN... |
297 |
KUNIT_EXPECT_KASAN_FAIL(test, *(ptr + 8) = 'x'); |
3f15801cd lib: add kasan te... |
298 |
} |
73228c7ec KASAN: port KASAN... |
299 |
static void kmalloc_uaf_memset(struct kunit *test) |
3f15801cd lib: add kasan te... |
300 301 302 |
{ char *ptr; size_t size = 33; |
3f15801cd lib: add kasan te... |
303 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
304 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
3f15801cd lib: add kasan te... |
305 306 |
kfree(ptr); |
73228c7ec KASAN: port KASAN... |
307 |
KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr, 0, size)); |
3f15801cd lib: add kasan te... |
308 |
} |
73228c7ec KASAN: port KASAN... |
309 |
static void kmalloc_uaf2(struct kunit *test) |
3f15801cd lib: add kasan te... |
310 311 312 |
{ char *ptr1, *ptr2; size_t size = 43; |
3f15801cd lib: add kasan te... |
313 |
ptr1 = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
314 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1); |
3f15801cd lib: add kasan te... |
315 316 |
kfree(ptr1); |
73228c7ec KASAN: port KASAN... |
317 |
|
3f15801cd lib: add kasan te... |
318 |
ptr2 = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
319 320 321 322 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2); KUNIT_EXPECT_KASAN_FAIL(test, ptr1[40] = 'x'); KUNIT_EXPECT_PTR_NE(test, ptr1, ptr2); |
3f15801cd lib: add kasan te... |
323 |
|
3f15801cd lib: add kasan te... |
324 325 |
kfree(ptr2); } |
73228c7ec KASAN: port KASAN... |
326 |
static void kfree_via_page(struct kunit *test) |
b92a953cb lib/test_kasan.c:... |
327 328 329 330 331 |
{ char *ptr; size_t size = 8; struct page *page; unsigned long offset; |
b92a953cb lib/test_kasan.c:... |
332 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
333 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
b92a953cb lib/test_kasan.c:... |
334 335 336 337 338 |
page = virt_to_page(ptr); offset = offset_in_page(ptr); kfree(page_address(page) + offset); } |
73228c7ec KASAN: port KASAN... |
339 |
static void kfree_via_phys(struct kunit *test) |
b92a953cb lib/test_kasan.c:... |
340 341 342 343 |
{ char *ptr; size_t size = 8; phys_addr_t phys; |
b92a953cb lib/test_kasan.c:... |
344 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
345 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
b92a953cb lib/test_kasan.c:... |
346 347 348 349 |
phys = virt_to_phys(ptr); kfree(phys_to_virt(phys)); } |
73228c7ec KASAN: port KASAN... |
350 |
static void kmem_cache_oob(struct kunit *test) |
3f15801cd lib: add kasan te... |
351 352 353 354 355 356 |
{ char *p; size_t size = 200; struct kmem_cache *cache = kmem_cache_create("test_cache", size, 0, 0, NULL); |
73228c7ec KASAN: port KASAN... |
357 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache); |
3f15801cd lib: add kasan te... |
358 359 |
p = kmem_cache_alloc(cache, GFP_KERNEL); if (!p) { |
73228c7ec KASAN: port KASAN... |
360 361 |
kunit_err(test, "Allocation failed: %s ", __func__); |
3f15801cd lib: add kasan te... |
362 363 364 |
kmem_cache_destroy(cache); return; } |
73228c7ec KASAN: port KASAN... |
365 |
KUNIT_EXPECT_KASAN_FAIL(test, *p = p[size + OOB_TAG_OFF]); |
3f15801cd lib: add kasan te... |
366 367 368 |
kmem_cache_free(cache, p); kmem_cache_destroy(cache); } |
73228c7ec KASAN: port KASAN... |
369 |
static void memcg_accounted_kmem_cache(struct kunit *test) |
0386bf385 kasan: add memcg ... |
370 371 372 373 374 375 376 |
{ int i; char *p; size_t size = 200; struct kmem_cache *cache; cache = kmem_cache_create("test_cache", size, 0, SLAB_ACCOUNT, NULL); |
73228c7ec KASAN: port KASAN... |
377 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache); |
0386bf385 kasan: add memcg ... |
378 |
|
0386bf385 kasan: add memcg ... |
379 380 381 382 383 384 |
/* * Several allocations with a delay to allow for lazy per memcg kmem * cache creation. */ for (i = 0; i < 5; i++) { p = kmem_cache_alloc(cache, GFP_KERNEL); |
dc2bf000a lib/test: delete ... |
385 |
if (!p) |
0386bf385 kasan: add memcg ... |
386 |
goto free_cache; |
dc2bf000a lib/test: delete ... |
387 |
|
0386bf385 kasan: add memcg ... |
388 389 390 391 392 393 394 |
kmem_cache_free(cache, p); msleep(100); } free_cache: kmem_cache_destroy(cache); } |
3f15801cd lib: add kasan te... |
395 |
static char global_array[10]; |
73228c7ec KASAN: port KASAN... |
396 |
static void kasan_global_oob(struct kunit *test) |
3f15801cd lib: add kasan te... |
397 398 399 |
{ volatile int i = 3; char *p = &global_array[ARRAY_SIZE(global_array) + i]; |
58b999d7a kasan: adopt KUNI... |
400 401 402 403 404 |
/* Only generic mode instruments globals. */ if (!IS_ENABLED(CONFIG_KASAN_GENERIC)) { kunit_info(test, "CONFIG_KASAN_GENERIC required"); return; } |
73228c7ec KASAN: port KASAN... |
405 |
KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p); |
3f15801cd lib: add kasan te... |
406 |
} |
73228c7ec KASAN: port KASAN... |
407 |
static void ksize_unpoisons_memory(struct kunit *test) |
96fe805fb mm, kasan: add a ... |
408 409 |
{ char *ptr; |
48c232395 kasan: remove red... |
410 |
size_t size = 123, real_size; |
96fe805fb mm, kasan: add a ... |
411 |
|
96fe805fb mm, kasan: add a ... |
412 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
413 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
96fe805fb mm, kasan: add a ... |
414 415 416 417 |
real_size = ksize(ptr); /* This access doesn't trigger an error. */ ptr[size] = 'x'; /* This one does. */ |
73228c7ec KASAN: port KASAN... |
418 |
KUNIT_EXPECT_KASAN_FAIL(test, ptr[real_size] = 'y'); |
96fe805fb mm, kasan: add a ... |
419 420 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
421 |
static void kasan_stack_oob(struct kunit *test) |
eae08dcab kasan/tests: add ... |
422 |
{ |
73228c7ec KASAN: port KASAN... |
423 424 425 |
char stack_array[10]; volatile int i = OOB_TAG_OFF; char *p = &stack_array[ARRAY_SIZE(stack_array) + i]; |
eae08dcab kasan/tests: add ... |
426 |
|
73228c7ec KASAN: port KASAN... |
427 428 |
if (!IS_ENABLED(CONFIG_KASAN_STACK)) { kunit_info(test, "CONFIG_KASAN_STACK is not enabled"); |
eae08dcab kasan/tests: add ... |
429 430 |
return; } |
73228c7ec KASAN: port KASAN... |
431 |
KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p); |
eae08dcab kasan/tests: add ... |
432 |
} |
73228c7ec KASAN: port KASAN... |
433 |
static void kasan_alloca_oob_left(struct kunit *test) |
00a14294b kasan: add tests ... |
434 435 436 437 |
{ volatile int i = 10; char alloca_array[i]; char *p = alloca_array - 1; |
58b999d7a kasan: adopt KUNI... |
438 439 440 441 442 |
/* Only generic mode instruments dynamic allocas. */ if (!IS_ENABLED(CONFIG_KASAN_GENERIC)) { kunit_info(test, "CONFIG_KASAN_GENERIC required"); return; } |
73228c7ec KASAN: port KASAN... |
443 444 445 446 447 448 |
if (!IS_ENABLED(CONFIG_KASAN_STACK)) { kunit_info(test, "CONFIG_KASAN_STACK is not enabled"); return; } KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p); |
00a14294b kasan: add tests ... |
449 |
} |
73228c7ec KASAN: port KASAN... |
450 |
static void kasan_alloca_oob_right(struct kunit *test) |
00a14294b kasan: add tests ... |
451 452 453 454 |
{ volatile int i = 10; char alloca_array[i]; char *p = alloca_array + i; |
58b999d7a kasan: adopt KUNI... |
455 456 457 458 459 |
/* Only generic mode instruments dynamic allocas. */ if (!IS_ENABLED(CONFIG_KASAN_GENERIC)) { kunit_info(test, "CONFIG_KASAN_GENERIC required"); return; } |
73228c7ec KASAN: port KASAN... |
460 461 462 463 464 465 |
if (!IS_ENABLED(CONFIG_KASAN_STACK)) { kunit_info(test, "CONFIG_KASAN_STACK is not enabled"); return; } KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p); |
00a14294b kasan: add tests ... |
466 |
} |
73228c7ec KASAN: port KASAN... |
467 |
static void kmem_cache_double_free(struct kunit *test) |
b1d572893 kasan: detect inv... |
468 469 470 471 472 473 |
{ char *p; size_t size = 200; struct kmem_cache *cache; cache = kmem_cache_create("test_cache", size, 0, 0, NULL); |
73228c7ec KASAN: port KASAN... |
474 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache); |
b1d572893 kasan: detect inv... |
475 476 |
p = kmem_cache_alloc(cache, GFP_KERNEL); if (!p) { |
73228c7ec KASAN: port KASAN... |
477 478 |
kunit_err(test, "Allocation failed: %s ", __func__); |
b1d572893 kasan: detect inv... |
479 480 481 482 483 |
kmem_cache_destroy(cache); return; } kmem_cache_free(cache, p); |
73228c7ec KASAN: port KASAN... |
484 |
KUNIT_EXPECT_KASAN_FAIL(test, kmem_cache_free(cache, p)); |
b1d572893 kasan: detect inv... |
485 486 |
kmem_cache_destroy(cache); } |
73228c7ec KASAN: port KASAN... |
487 |
static void kmem_cache_invalid_free(struct kunit *test) |
b1d572893 kasan: detect inv... |
488 489 490 491 492 493 494 |
{ char *p; size_t size = 200; struct kmem_cache *cache; cache = kmem_cache_create("test_cache", size, 0, SLAB_TYPESAFE_BY_RCU, NULL); |
73228c7ec KASAN: port KASAN... |
495 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache); |
b1d572893 kasan: detect inv... |
496 497 |
p = kmem_cache_alloc(cache, GFP_KERNEL); if (!p) { |
73228c7ec KASAN: port KASAN... |
498 499 |
kunit_err(test, "Allocation failed: %s ", __func__); |
b1d572893 kasan: detect inv... |
500 501 502 |
kmem_cache_destroy(cache); return; } |
91c93ed07 kasan: fix invali... |
503 |
/* Trigger invalid free, the object doesn't get freed */ |
73228c7ec KASAN: port KASAN... |
504 |
KUNIT_EXPECT_KASAN_FAIL(test, kmem_cache_free(cache, p + 1)); |
91c93ed07 kasan: fix invali... |
505 506 507 508 509 510 |
/* * Properly free the object to prevent the "Objects remaining in * test_cache on __kmem_cache_shutdown" BUG failure. */ kmem_cache_free(cache, p); |
b1d572893 kasan: detect inv... |
511 512 |
kmem_cache_destroy(cache); } |
73228c7ec KASAN: port KASAN... |
513 |
static void kasan_memchr(struct kunit *test) |
0c96350a2 lib/test_kasan.c:... |
514 515 516 |
{ char *ptr; size_t size = 24; |
73228c7ec KASAN: port KASAN... |
517 518 519 520 |
/* See https://bugzilla.kernel.org/show_bug.cgi?id=206337 */ if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) { kunit_info(test, "str* functions are not instrumented with CONFIG_AMD_MEM_ENCRYPT"); |
0c96350a2 lib/test_kasan.c:... |
521 |
return; |
73228c7ec KASAN: port KASAN... |
522 |
} |
58b999d7a kasan: adopt KUNI... |
523 524 |
if (OOB_TAG_OFF) size = round_up(size, OOB_TAG_OFF); |
73228c7ec KASAN: port KASAN... |
525 526 527 528 529 |
ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); KUNIT_EXPECT_KASAN_FAIL(test, kasan_ptr_result = memchr(ptr, '1', size + 1)); |
0c96350a2 lib/test_kasan.c:... |
530 |
|
0c96350a2 lib/test_kasan.c:... |
531 532 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
533 |
static void kasan_memcmp(struct kunit *test) |
0c96350a2 lib/test_kasan.c:... |
534 535 536 537 |
{ char *ptr; size_t size = 24; int arr[9]; |
73228c7ec KASAN: port KASAN... |
538 539 540 541 |
/* See https://bugzilla.kernel.org/show_bug.cgi?id=206337 */ if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) { kunit_info(test, "str* functions are not instrumented with CONFIG_AMD_MEM_ENCRYPT"); |
0c96350a2 lib/test_kasan.c:... |
542 |
return; |
73228c7ec KASAN: port KASAN... |
543 |
} |
0c96350a2 lib/test_kasan.c:... |
544 |
|
58b999d7a kasan: adopt KUNI... |
545 546 |
if (OOB_TAG_OFF) size = round_up(size, OOB_TAG_OFF); |
73228c7ec KASAN: port KASAN... |
547 548 |
ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
0c96350a2 lib/test_kasan.c:... |
549 |
memset(arr, 0, sizeof(arr)); |
73228c7ec KASAN: port KASAN... |
550 551 552 |
KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = memcmp(ptr, arr, size+1)); |
0c96350a2 lib/test_kasan.c:... |
553 554 |
kfree(ptr); } |
73228c7ec KASAN: port KASAN... |
555 |
static void kasan_strings(struct kunit *test) |
0c96350a2 lib/test_kasan.c:... |
556 557 558 |
{ char *ptr; size_t size = 24; |
73228c7ec KASAN: port KASAN... |
559 560 561 562 |
/* See https://bugzilla.kernel.org/show_bug.cgi?id=206337 */ if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) { kunit_info(test, "str* functions are not instrumented with CONFIG_AMD_MEM_ENCRYPT"); |
0c96350a2 lib/test_kasan.c:... |
563 |
return; |
73228c7ec KASAN: port KASAN... |
564 565 566 567 |
} ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
0c96350a2 lib/test_kasan.c:... |
568 569 570 571 572 573 574 575 576 577 |
kfree(ptr); /* * Try to cause only 1 invalid access (less spam in dmesg). * For that we need ptr to point to zeroed byte. * Skip metadata that could be stored in freed object so ptr * will likely point to zeroed byte. */ ptr += 16; |
73228c7ec KASAN: port KASAN... |
578 |
KUNIT_EXPECT_KASAN_FAIL(test, kasan_ptr_result = strchr(ptr, '1')); |
0c96350a2 lib/test_kasan.c:... |
579 |
|
73228c7ec KASAN: port KASAN... |
580 |
KUNIT_EXPECT_KASAN_FAIL(test, kasan_ptr_result = strrchr(ptr, '1')); |
0c96350a2 lib/test_kasan.c:... |
581 |
|
73228c7ec KASAN: port KASAN... |
582 |
KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = strcmp(ptr, "2")); |
0c96350a2 lib/test_kasan.c:... |
583 |
|
73228c7ec KASAN: port KASAN... |
584 |
KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = strncmp(ptr, "2", 1)); |
0c96350a2 lib/test_kasan.c:... |
585 |
|
73228c7ec KASAN: port KASAN... |
586 |
KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = strlen(ptr)); |
0c96350a2 lib/test_kasan.c:... |
587 |
|
73228c7ec KASAN: port KASAN... |
588 |
KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = strnlen(ptr, 1)); |
0c96350a2 lib/test_kasan.c:... |
589 |
} |
58b999d7a kasan: adopt KUNI... |
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 |
static void kasan_bitops_modify(struct kunit *test, int nr, void *addr) { KUNIT_EXPECT_KASAN_FAIL(test, set_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, __set_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, clear_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, __clear_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, clear_bit_unlock(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, __clear_bit_unlock(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, change_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, __change_bit(nr, addr)); } static void kasan_bitops_test_and_modify(struct kunit *test, int nr, void *addr) { KUNIT_EXPECT_KASAN_FAIL(test, test_and_set_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, __test_and_set_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, test_and_set_bit_lock(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, test_and_clear_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, __test_and_clear_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, test_and_change_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, __test_and_change_bit(nr, addr)); KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = test_bit(nr, addr)); #if defined(clear_bit_unlock_is_negative_byte) KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = clear_bit_unlock_is_negative_byte(nr, addr)); #endif } static void kasan_bitops_generic(struct kunit *test) |
19a33ca6c lib/test_kasan: a... |
620 |
{ |
58b999d7a kasan: adopt KUNI... |
621 622 623 624 625 626 627 628 |
long *bits; /* This test is specifically crafted for the generic mode. */ if (!IS_ENABLED(CONFIG_KASAN_GENERIC)) { kunit_info(test, "CONFIG_KASAN_GENERIC required "); return; } |
19a33ca6c lib/test_kasan: a... |
629 630 631 632 |
/* * Allocate 1 more byte, which causes kzalloc to round up to 16-bytes; * this way we do not actually corrupt other memory. */ |
58b999d7a kasan: adopt KUNI... |
633 |
bits = kzalloc(sizeof(*bits) + 1, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
634 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bits); |
19a33ca6c lib/test_kasan: a... |
635 636 637 638 639 640 |
/* * Below calls try to access bit within allocated memory; however, the * below accesses are still out-of-bounds, since bitops are defined to * operate on the whole long the bit is in. */ |
58b999d7a kasan: adopt KUNI... |
641 |
kasan_bitops_modify(test, BITS_PER_LONG, bits); |
19a33ca6c lib/test_kasan: a... |
642 643 644 645 |
/* * Below calls try to access bit beyond allocated memory. */ |
58b999d7a kasan: adopt KUNI... |
646 |
kasan_bitops_test_and_modify(test, BITS_PER_LONG + BITS_PER_BYTE, bits); |
19a33ca6c lib/test_kasan: a... |
647 |
|
58b999d7a kasan: adopt KUNI... |
648 649 |
kfree(bits); } |
19a33ca6c lib/test_kasan: a... |
650 |
|
58b999d7a kasan: adopt KUNI... |
651 652 653 |
static void kasan_bitops_tags(struct kunit *test) { long *bits; |
19a33ca6c lib/test_kasan: a... |
654 |
|
58b999d7a kasan: adopt KUNI... |
655 656 657 658 659 660 |
/* This test is specifically crafted for the tag-based mode. */ if (IS_ENABLED(CONFIG_KASAN_GENERIC)) { kunit_info(test, "CONFIG_KASAN_SW_TAGS required "); return; } |
19a33ca6c lib/test_kasan: a... |
661 |
|
58b999d7a kasan: adopt KUNI... |
662 663 664 |
/* Allocation size will be rounded to up granule size, which is 16. */ bits = kzalloc(sizeof(*bits), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bits); |
19a33ca6c lib/test_kasan: a... |
665 |
|
58b999d7a kasan: adopt KUNI... |
666 667 668 |
/* Do the accesses past the 16 allocated bytes. */ kasan_bitops_modify(test, BITS_PER_LONG, &bits[1]); kasan_bitops_test_and_modify(test, BITS_PER_LONG + BITS_PER_BYTE, &bits[1]); |
19a33ca6c lib/test_kasan: a... |
669 |
|
19a33ca6c lib/test_kasan: a... |
670 671 |
kfree(bits); } |
73228c7ec KASAN: port KASAN... |
672 |
static void kmalloc_double_kzfree(struct kunit *test) |
bb104ed78 lib/test_kasan: A... |
673 674 675 |
{ char *ptr; size_t size = 16; |
bb104ed78 lib/test_kasan: A... |
676 |
ptr = kmalloc(size, GFP_KERNEL); |
73228c7ec KASAN: port KASAN... |
677 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
bb104ed78 lib/test_kasan: A... |
678 |
|
453431a54 mm, treewide: ren... |
679 |
kfree_sensitive(ptr); |
73228c7ec KASAN: port KASAN... |
680 |
KUNIT_EXPECT_KASAN_FAIL(test, kfree_sensitive(ptr)); |
bb104ed78 lib/test_kasan: A... |
681 |
} |
73228c7ec KASAN: port KASAN... |
682 |
static void vmalloc_oob(struct kunit *test) |
065139169 kasan: add test f... |
683 684 |
{ void *area; |
73228c7ec KASAN: port KASAN... |
685 686 687 688 |
if (!IS_ENABLED(CONFIG_KASAN_VMALLOC)) { kunit_info(test, "CONFIG_KASAN_VMALLOC is not enabled."); return; } |
065139169 kasan: add test f... |
689 690 691 692 693 694 |
/* * We have to be careful not to hit the guard page. * The MMU will catch that and crash us. */ area = vmalloc(3000); |
73228c7ec KASAN: port KASAN... |
695 |
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, area); |
065139169 kasan: add test f... |
696 |
|
73228c7ec KASAN: port KASAN... |
697 |
KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)area)[3100]); |
065139169 kasan: add test f... |
698 699 |
vfree(area); } |
387d6e466 kasan: add tests ... |
700 |
|
73228c7ec KASAN: port KASAN... |
701 702 703 704 705 706 707 708 709 710 711 |
static struct kunit_case kasan_kunit_test_cases[] = { KUNIT_CASE(kmalloc_oob_right), KUNIT_CASE(kmalloc_oob_left), KUNIT_CASE(kmalloc_node_oob_right), KUNIT_CASE(kmalloc_pagealloc_oob_right), KUNIT_CASE(kmalloc_pagealloc_uaf), KUNIT_CASE(kmalloc_pagealloc_invalid_free), KUNIT_CASE(kmalloc_large_oob_right), KUNIT_CASE(kmalloc_oob_krealloc_more), KUNIT_CASE(kmalloc_oob_krealloc_less), KUNIT_CASE(kmalloc_oob_16), |
58b999d7a kasan: adopt KUNI... |
712 |
KUNIT_CASE(kmalloc_uaf_16), |
73228c7ec KASAN: port KASAN... |
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 |
KUNIT_CASE(kmalloc_oob_in_memset), KUNIT_CASE(kmalloc_oob_memset_2), KUNIT_CASE(kmalloc_oob_memset_4), KUNIT_CASE(kmalloc_oob_memset_8), KUNIT_CASE(kmalloc_oob_memset_16), KUNIT_CASE(kmalloc_memmove_invalid_size), KUNIT_CASE(kmalloc_uaf), KUNIT_CASE(kmalloc_uaf_memset), KUNIT_CASE(kmalloc_uaf2), KUNIT_CASE(kfree_via_page), KUNIT_CASE(kfree_via_phys), KUNIT_CASE(kmem_cache_oob), KUNIT_CASE(memcg_accounted_kmem_cache), KUNIT_CASE(kasan_global_oob), KUNIT_CASE(kasan_stack_oob), KUNIT_CASE(kasan_alloca_oob_left), KUNIT_CASE(kasan_alloca_oob_right), KUNIT_CASE(ksize_unpoisons_memory), KUNIT_CASE(kmem_cache_double_free), KUNIT_CASE(kmem_cache_invalid_free), KUNIT_CASE(kasan_memchr), KUNIT_CASE(kasan_memcmp), KUNIT_CASE(kasan_strings), |
58b999d7a kasan: adopt KUNI... |
736 737 |
KUNIT_CASE(kasan_bitops_generic), KUNIT_CASE(kasan_bitops_tags), |
73228c7ec KASAN: port KASAN... |
738 739 740 741 742 743 744 745 746 747 748 749 750 |
KUNIT_CASE(kmalloc_double_kzfree), KUNIT_CASE(vmalloc_oob), {} }; static struct kunit_suite kasan_kunit_test_suite = { .name = "kasan", .init = kasan_test_init, .test_cases = kasan_kunit_test_cases, .exit = kasan_test_exit, }; kunit_test_suite(kasan_kunit_test_suite); |
3f15801cd lib: add kasan te... |
751 |
|
3f15801cd lib: add kasan te... |
752 |
MODULE_LICENSE("GPL"); |