hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/lib/test_kasan.c
....@@ -1,371 +1,601 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 *
34 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
45 * Author: Andrey Ryabinin <a.ryabinin@samsung.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
9
- *
106 */
117
12
-#define pr_fmt(fmt) "kasan test: %s " fmt, __func__
13
-
8
+#include <linux/bitops.h>
149 #include <linux/delay.h>
10
+#include <linux/kasan.h>
1511 #include <linux/kernel.h>
16
-#include <linux/mman.h>
1712 #include <linux/mm.h>
13
+#include <linux/mman.h>
14
+#include <linux/module.h>
1815 #include <linux/printk.h>
16
+#include <linux/random.h>
1917 #include <linux/slab.h>
2018 #include <linux/string.h>
2119 #include <linux/uaccess.h>
22
-#include <linux/module.h>
23
-#include <linux/kasan.h>
20
+#include <linux/io.h>
21
+#include <linux/vmalloc.h>
22
+
23
+#include <asm/page.h>
24
+
25
+#include <kunit/test.h>
26
+
27
+#include "../mm/kasan/kasan.h"
28
+
29
+#define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_GRANULE_SIZE)
2430
2531 /*
26
- * Note: test functions are marked noinline so that their names appear in
27
- * reports.
32
+ * Some tests use these global variables to store return values from function
33
+ * calls that could otherwise be eliminated by the compiler as dead code.
2834 */
35
+void *kasan_ptr_result;
36
+int kasan_int_result;
2937
30
-static noinline void __init kmalloc_oob_right(void)
38
+static struct kunit_resource resource;
39
+static struct kunit_kasan_expectation fail_data;
40
+static bool multishot;
41
+
42
+/*
43
+ * Temporarily enable multi-shot mode. Otherwise, KASAN would only report the
44
+ * first detected bug and panic the kernel if panic_on_warn is enabled. For
45
+ * hardware tag-based KASAN also allow tag checking to be reenabled for each
46
+ * test, see the comment for KUNIT_EXPECT_KASAN_FAIL().
47
+ */
48
+static int kasan_test_init(struct kunit *test)
49
+{
50
+ if (!kasan_enabled()) {
51
+ kunit_err(test, "can't run KASAN tests with KASAN disabled");
52
+ return -1;
53
+ }
54
+
55
+ multishot = kasan_save_enable_multi_shot();
56
+ kasan_set_tagging_report_once(false);
57
+ return 0;
58
+}
59
+
60
+static void kasan_test_exit(struct kunit *test)
61
+{
62
+ kasan_set_tagging_report_once(true);
63
+ kasan_restore_multi_shot(multishot);
64
+}
65
+
66
+/**
67
+ * KUNIT_EXPECT_KASAN_FAIL() - check that the executed expression produces a
68
+ * KASAN report; causes a test failure otherwise. This relies on a KUnit
69
+ * resource named "kasan_data". Do not use this name for KUnit resources
70
+ * outside of KASAN tests.
71
+ *
72
+ * For hardware tag-based KASAN in sync mode, when a tag fault happens, tag
73
+ * checking is auto-disabled. When this happens, this test handler reenables
74
+ * tag checking. As tag checking can be only disabled or enabled per CPU,
75
+ * this handler disables migration (preemption).
76
+ *
77
+ * Since the compiler doesn't see that the expression can change the fail_data
78
+ * fields, it can reorder or optimize away the accesses to those fields.
79
+ * Use READ/WRITE_ONCE() for the accesses and compiler barriers around the
80
+ * expression to prevent that.
81
+ */
82
+#define KUNIT_EXPECT_KASAN_FAIL(test, expression) do { \
83
+ if (IS_ENABLED(CONFIG_KASAN_HW_TAGS) && \
84
+ !kasan_async_mode_enabled()) \
85
+ migrate_disable(); \
86
+ WRITE_ONCE(fail_data.report_expected, true); \
87
+ WRITE_ONCE(fail_data.report_found, false); \
88
+ kunit_add_named_resource(test, \
89
+ NULL, \
90
+ NULL, \
91
+ &resource, \
92
+ "kasan_data", &fail_data); \
93
+ barrier(); \
94
+ expression; \
95
+ barrier(); \
96
+ if (kasan_async_mode_enabled()) \
97
+ kasan_force_async_fault(); \
98
+ barrier(); \
99
+ KUNIT_EXPECT_EQ(test, \
100
+ READ_ONCE(fail_data.report_expected), \
101
+ READ_ONCE(fail_data.report_found)); \
102
+ if (IS_ENABLED(CONFIG_KASAN_HW_TAGS) && \
103
+ !kasan_async_mode_enabled()) { \
104
+ if (READ_ONCE(fail_data.report_found)) \
105
+ kasan_enable_tagging_sync(); \
106
+ migrate_enable(); \
107
+ } \
108
+} while (0)
109
+
110
+#define KASAN_TEST_NEEDS_CONFIG_ON(test, config) do { \
111
+ if (!IS_ENABLED(config)) { \
112
+ kunit_info((test), "skipping, " #config " required"); \
113
+ return; \
114
+ } \
115
+} while (0)
116
+
117
+#define KASAN_TEST_NEEDS_CONFIG_OFF(test, config) do { \
118
+ if (IS_ENABLED(config)) { \
119
+ kunit_info((test), "skipping, " #config " enabled"); \
120
+ return; \
121
+ } \
122
+} while (0)
123
+
124
+static void kmalloc_oob_right(struct kunit *test)
31125 {
32126 char *ptr;
33127 size_t size = 123;
34128
35
- pr_info("out-of-bounds to right\n");
36129 ptr = kmalloc(size, GFP_KERNEL);
37
- if (!ptr) {
38
- pr_err("Allocation failed\n");
39
- return;
40
- }
130
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
41131
42
- ptr[size] = 'x';
132
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[size + OOB_TAG_OFF] = 'x');
43133 kfree(ptr);
44134 }
45135
46
-static noinline void __init kmalloc_oob_left(void)
136
+static void kmalloc_oob_left(struct kunit *test)
47137 {
48138 char *ptr;
49139 size_t size = 15;
50140
51
- pr_info("out-of-bounds to left\n");
52141 ptr = kmalloc(size, GFP_KERNEL);
53
- if (!ptr) {
54
- pr_err("Allocation failed\n");
55
- return;
56
- }
142
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
57143
58
- *ptr = *(ptr - 1);
144
+ KUNIT_EXPECT_KASAN_FAIL(test, *ptr = *(ptr - 1));
59145 kfree(ptr);
60146 }
61147
62
-static noinline void __init kmalloc_node_oob_right(void)
148
+static void kmalloc_node_oob_right(struct kunit *test)
63149 {
64150 char *ptr;
65151 size_t size = 4096;
66152
67
- pr_info("kmalloc_node(): out-of-bounds to right\n");
68153 ptr = kmalloc_node(size, GFP_KERNEL, 0);
69
- if (!ptr) {
70
- pr_err("Allocation failed\n");
71
- return;
72
- }
154
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
73155
74
- ptr[size] = 0;
156
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[size] = 0);
75157 kfree(ptr);
76158 }
77159
78
-#ifdef CONFIG_SLUB
79
-static noinline void __init kmalloc_pagealloc_oob_right(void)
160
+/*
161
+ * These kmalloc_pagealloc_* tests try allocating a memory chunk that doesn't
162
+ * fit into a slab cache and therefore is allocated via the page allocator
163
+ * fallback. Since this kind of fallback is only implemented for SLUB, these
164
+ * tests are limited to that allocator.
165
+ */
166
+static void kmalloc_pagealloc_oob_right(struct kunit *test)
80167 {
81168 char *ptr;
82169 size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
83170
84
- /* Allocate a chunk that does not fit into a SLUB cache to trigger
85
- * the page allocator fallback.
171
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_SLUB);
172
+
173
+ ptr = kmalloc(size, GFP_KERNEL);
174
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
175
+
176
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[size + OOB_TAG_OFF] = 0);
177
+
178
+ kfree(ptr);
179
+}
180
+
181
+static void kmalloc_pagealloc_uaf(struct kunit *test)
182
+{
183
+ char *ptr;
184
+ size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
185
+
186
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_SLUB);
187
+
188
+ ptr = kmalloc(size, GFP_KERNEL);
189
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
190
+ kfree(ptr);
191
+
192
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] = 0);
193
+}
194
+
195
+static void kmalloc_pagealloc_invalid_free(struct kunit *test)
196
+{
197
+ char *ptr;
198
+ size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
199
+
200
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_SLUB);
201
+
202
+ ptr = kmalloc(size, GFP_KERNEL);
203
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
204
+
205
+ KUNIT_EXPECT_KASAN_FAIL(test, kfree(ptr + 1));
206
+}
207
+
208
+static void pagealloc_oob_right(struct kunit *test)
209
+{
210
+ char *ptr;
211
+ struct page *pages;
212
+ size_t order = 4;
213
+ size_t size = (1UL << (PAGE_SHIFT + order));
214
+
215
+ /*
216
+ * With generic KASAN page allocations have no redzones, thus
217
+ * out-of-bounds detection is not guaranteed.
218
+ * See https://bugzilla.kernel.org/show_bug.cgi?id=210503.
86219 */
87
- pr_info("kmalloc pagealloc allocation: out-of-bounds to right\n");
88
- ptr = kmalloc(size, GFP_KERNEL);
89
- if (!ptr) {
90
- pr_err("Allocation failed\n");
91
- return;
92
- }
220
+ KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_KASAN_GENERIC);
93221
94
- ptr[size] = 0;
95
- kfree(ptr);
222
+ pages = alloc_pages(GFP_KERNEL, order);
223
+ ptr = page_address(pages);
224
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
225
+
226
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[size] = 0);
227
+ free_pages((unsigned long)ptr, order);
96228 }
97229
98
-static noinline void __init kmalloc_pagealloc_uaf(void)
230
+static void pagealloc_uaf(struct kunit *test)
99231 {
100232 char *ptr;
101
- size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
233
+ struct page *pages;
234
+ size_t order = 4;
102235
103
- pr_info("kmalloc pagealloc allocation: use-after-free\n");
104
- ptr = kmalloc(size, GFP_KERNEL);
105
- if (!ptr) {
106
- pr_err("Allocation failed\n");
107
- return;
108
- }
236
+ pages = alloc_pages(GFP_KERNEL, order);
237
+ ptr = page_address(pages);
238
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
239
+ free_pages((unsigned long)ptr, order);
109240
110
- kfree(ptr);
111
- ptr[0] = 0;
241
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] = 0);
112242 }
113243
114
-static noinline void __init kmalloc_pagealloc_invalid_free(void)
115
-{
116
- char *ptr;
117
- size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
118
-
119
- pr_info("kmalloc pagealloc allocation: invalid-free\n");
120
- ptr = kmalloc(size, GFP_KERNEL);
121
- if (!ptr) {
122
- pr_err("Allocation failed\n");
123
- return;
124
- }
125
-
126
- kfree(ptr + 1);
127
-}
128
-#endif
129
-
130
-static noinline void __init kmalloc_large_oob_right(void)
244
+static void kmalloc_large_oob_right(struct kunit *test)
131245 {
132246 char *ptr;
133247 size_t size = KMALLOC_MAX_CACHE_SIZE - 256;
134
- /* Allocate a chunk that is large enough, but still fits into a slab
248
+
249
+ /*
250
+ * Allocate a chunk that is large enough, but still fits into a slab
135251 * and does not trigger the page allocator fallback in SLUB.
136252 */
137
- pr_info("kmalloc large allocation: out-of-bounds to right\n");
138253 ptr = kmalloc(size, GFP_KERNEL);
139
- if (!ptr) {
140
- pr_err("Allocation failed\n");
141
- return;
142
- }
254
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
143255
144
- ptr[size] = 0;
256
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[size] = 0);
145257 kfree(ptr);
146258 }
147259
148
-static noinline void __init kmalloc_oob_krealloc_more(void)
260
+static void krealloc_more_oob_helper(struct kunit *test,
261
+ size_t size1, size_t size2)
149262 {
150263 char *ptr1, *ptr2;
151
- size_t size1 = 17;
152
- size_t size2 = 19;
264
+ size_t middle;
153265
154
- pr_info("out-of-bounds after krealloc more\n");
266
+ KUNIT_ASSERT_LT(test, size1, size2);
267
+ middle = size1 + (size2 - size1) / 2;
268
+
155269 ptr1 = kmalloc(size1, GFP_KERNEL);
156
- ptr2 = krealloc(ptr1, size2, GFP_KERNEL);
157
- if (!ptr1 || !ptr2) {
158
- pr_err("Allocation failed\n");
159
- kfree(ptr1);
160
- kfree(ptr2);
161
- return;
162
- }
270
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1);
163271
164
- ptr2[size2] = 'x';
272
+ ptr2 = krealloc(ptr1, size2, GFP_KERNEL);
273
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
274
+
275
+ /* All offsets up to size2 must be accessible. */
276
+ ptr2[size1 - 1] = 'x';
277
+ ptr2[size1] = 'x';
278
+ ptr2[middle] = 'x';
279
+ ptr2[size2 - 1] = 'x';
280
+
281
+ /* Generic mode is precise, so unaligned size2 must be inaccessible. */
282
+ if (IS_ENABLED(CONFIG_KASAN_GENERIC))
283
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr2[size2] = 'x');
284
+
285
+ /* For all modes first aligned offset after size2 must be inaccessible. */
286
+ KUNIT_EXPECT_KASAN_FAIL(test,
287
+ ptr2[round_up(size2, KASAN_GRANULE_SIZE)] = 'x');
288
+
165289 kfree(ptr2);
166290 }
167291
168
-static noinline void __init kmalloc_oob_krealloc_less(void)
292
+static void krealloc_less_oob_helper(struct kunit *test,
293
+ size_t size1, size_t size2)
169294 {
170295 char *ptr1, *ptr2;
171
- size_t size1 = 17;
172
- size_t size2 = 15;
296
+ size_t middle;
173297
174
- pr_info("out-of-bounds after krealloc less\n");
298
+ KUNIT_ASSERT_LT(test, size2, size1);
299
+ middle = size2 + (size1 - size2) / 2;
300
+
175301 ptr1 = kmalloc(size1, GFP_KERNEL);
302
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1);
303
+
176304 ptr2 = krealloc(ptr1, size2, GFP_KERNEL);
177
- if (!ptr1 || !ptr2) {
178
- pr_err("Allocation failed\n");
179
- kfree(ptr1);
180
- return;
181
- }
182
- ptr2[size2] = 'x';
305
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
306
+
307
+ /* Must be accessible for all modes. */
308
+ ptr2[size2 - 1] = 'x';
309
+
310
+ /* Generic mode is precise, so unaligned size2 must be inaccessible. */
311
+ if (IS_ENABLED(CONFIG_KASAN_GENERIC))
312
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr2[size2] = 'x');
313
+
314
+ /* For all modes first aligned offset after size2 must be inaccessible. */
315
+ KUNIT_EXPECT_KASAN_FAIL(test,
316
+ ptr2[round_up(size2, KASAN_GRANULE_SIZE)] = 'x');
317
+
318
+ /*
319
+ * For all modes all size2, middle, and size1 should land in separate
320
+ * granules and thus the latter two offsets should be inaccessible.
321
+ */
322
+ KUNIT_EXPECT_LE(test, round_up(size2, KASAN_GRANULE_SIZE),
323
+ round_down(middle, KASAN_GRANULE_SIZE));
324
+ KUNIT_EXPECT_LE(test, round_up(middle, KASAN_GRANULE_SIZE),
325
+ round_down(size1, KASAN_GRANULE_SIZE));
326
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr2[middle] = 'x');
327
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr2[size1 - 1] = 'x');
328
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr2[size1] = 'x');
329
+
183330 kfree(ptr2);
184331 }
185332
186
-static noinline void __init kmalloc_oob_16(void)
333
+static void krealloc_more_oob(struct kunit *test)
334
+{
335
+ krealloc_more_oob_helper(test, 201, 235);
336
+}
337
+
338
+static void krealloc_less_oob(struct kunit *test)
339
+{
340
+ krealloc_less_oob_helper(test, 235, 201);
341
+}
342
+
343
+static void krealloc_pagealloc_more_oob(struct kunit *test)
344
+{
345
+ /* page_alloc fallback in only implemented for SLUB. */
346
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_SLUB);
347
+
348
+ krealloc_more_oob_helper(test, KMALLOC_MAX_CACHE_SIZE + 201,
349
+ KMALLOC_MAX_CACHE_SIZE + 235);
350
+}
351
+
352
+static void krealloc_pagealloc_less_oob(struct kunit *test)
353
+{
354
+ /* page_alloc fallback in only implemented for SLUB. */
355
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_SLUB);
356
+
357
+ krealloc_less_oob_helper(test, KMALLOC_MAX_CACHE_SIZE + 235,
358
+ KMALLOC_MAX_CACHE_SIZE + 201);
359
+}
360
+
361
+/*
362
+ * Check that krealloc() detects a use-after-free, returns NULL,
363
+ * and doesn't unpoison the freed object.
364
+ */
365
+static void krealloc_uaf(struct kunit *test)
366
+{
367
+ char *ptr1, *ptr2;
368
+ int size1 = 201;
369
+ int size2 = 235;
370
+
371
+ ptr1 = kmalloc(size1, GFP_KERNEL);
372
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1);
373
+ kfree(ptr1);
374
+
375
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr2 = krealloc(ptr1, size2, GFP_KERNEL));
376
+ KUNIT_ASSERT_PTR_EQ(test, (void *)ptr2, NULL);
377
+ KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)ptr1);
378
+}
379
+
380
+static void kmalloc_oob_16(struct kunit *test)
187381 {
188382 struct {
189383 u64 words[2];
190384 } *ptr1, *ptr2;
191385
192
- pr_info("kmalloc out-of-bounds for 16-bytes access\n");
386
+ /* This test is specifically crafted for the generic mode. */
387
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_GENERIC);
388
+
193389 ptr1 = kmalloc(sizeof(*ptr1) - 3, GFP_KERNEL);
390
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1);
391
+
194392 ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL);
195
- if (!ptr1 || !ptr2) {
196
- pr_err("Allocation failed\n");
197
- kfree(ptr1);
198
- kfree(ptr2);
199
- return;
200
- }
201
- *ptr1 = *ptr2;
393
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
394
+
395
+ KUNIT_EXPECT_KASAN_FAIL(test, *ptr1 = *ptr2);
202396 kfree(ptr1);
203397 kfree(ptr2);
204398 }
205399
206
-static noinline void __init kmalloc_oob_memset_2(void)
400
+static void kmalloc_uaf_16(struct kunit *test)
401
+{
402
+ struct {
403
+ u64 words[2];
404
+ } *ptr1, *ptr2;
405
+
406
+ ptr1 = kmalloc(sizeof(*ptr1), GFP_KERNEL);
407
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1);
408
+
409
+ ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL);
410
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
411
+ kfree(ptr2);
412
+
413
+ KUNIT_EXPECT_KASAN_FAIL(test, *ptr1 = *ptr2);
414
+ kfree(ptr1);
415
+}
416
+
417
+static void kmalloc_oob_memset_2(struct kunit *test)
207418 {
208419 char *ptr;
209420 size_t size = 8;
210421
211
- pr_info("out-of-bounds in memset2\n");
212422 ptr = kmalloc(size, GFP_KERNEL);
213
- if (!ptr) {
214
- pr_err("Allocation failed\n");
215
- return;
216
- }
423
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
217424
218
- memset(ptr+7, 0, 2);
425
+ KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + 7 + OOB_TAG_OFF, 0, 2));
219426 kfree(ptr);
220427 }
221428
222
-static noinline void __init kmalloc_oob_memset_4(void)
429
+static void kmalloc_oob_memset_4(struct kunit *test)
223430 {
224431 char *ptr;
225432 size_t size = 8;
226433
227
- pr_info("out-of-bounds in memset4\n");
228434 ptr = kmalloc(size, GFP_KERNEL);
229
- if (!ptr) {
230
- pr_err("Allocation failed\n");
231
- return;
232
- }
435
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
233436
234
- memset(ptr+5, 0, 4);
437
+ KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + 5 + OOB_TAG_OFF, 0, 4));
235438 kfree(ptr);
236439 }
237440
238441
239
-static noinline void __init kmalloc_oob_memset_8(void)
442
+static void kmalloc_oob_memset_8(struct kunit *test)
240443 {
241444 char *ptr;
242445 size_t size = 8;
243446
244
- pr_info("out-of-bounds in memset8\n");
245447 ptr = kmalloc(size, GFP_KERNEL);
246
- if (!ptr) {
247
- pr_err("Allocation failed\n");
248
- return;
249
- }
448
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
250449
251
- memset(ptr+1, 0, 8);
450
+ KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + 1 + OOB_TAG_OFF, 0, 8));
252451 kfree(ptr);
253452 }
254453
255
-static noinline void __init kmalloc_oob_memset_16(void)
454
+static void kmalloc_oob_memset_16(struct kunit *test)
256455 {
257456 char *ptr;
258457 size_t size = 16;
259458
260
- pr_info("out-of-bounds in memset16\n");
261459 ptr = kmalloc(size, GFP_KERNEL);
262
- if (!ptr) {
263
- pr_err("Allocation failed\n");
264
- return;
265
- }
460
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
266461
267
- memset(ptr+1, 0, 16);
462
+ KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + 1 + OOB_TAG_OFF, 0, 16));
268463 kfree(ptr);
269464 }
270465
271
-static noinline void __init kmalloc_oob_in_memset(void)
466
+static void kmalloc_oob_in_memset(struct kunit *test)
272467 {
273468 char *ptr;
274469 size_t size = 666;
275470
276
- pr_info("out-of-bounds in memset\n");
277471 ptr = kmalloc(size, GFP_KERNEL);
278
- if (!ptr) {
279
- pr_err("Allocation failed\n");
280
- return;
281
- }
472
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
282473
283
- memset(ptr, 0, size+5);
474
+ KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr, 0, size + 5 + OOB_TAG_OFF));
284475 kfree(ptr);
285476 }
286477
287
-static noinline void __init kmalloc_uaf(void)
478
+static void kmalloc_memmove_invalid_size(struct kunit *test)
479
+{
480
+ char *ptr;
481
+ size_t size = 64;
482
+ volatile size_t invalid_size = -2;
483
+
484
+ ptr = kmalloc(size, GFP_KERNEL);
485
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
486
+
487
+ memset((char *)ptr, 0, 64);
488
+
489
+ KUNIT_EXPECT_KASAN_FAIL(test,
490
+ memmove((char *)ptr, (char *)ptr + 4, invalid_size));
491
+ kfree(ptr);
492
+}
493
+
494
+static void kmalloc_uaf(struct kunit *test)
288495 {
289496 char *ptr;
290497 size_t size = 10;
291498
292
- pr_info("use-after-free\n");
293499 ptr = kmalloc(size, GFP_KERNEL);
294
- if (!ptr) {
295
- pr_err("Allocation failed\n");
296
- return;
297
- }
500
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
298501
299502 kfree(ptr);
300
- *(ptr + 8) = 'x';
503
+ KUNIT_EXPECT_KASAN_FAIL(test, *(ptr + 8) = 'x');
301504 }
302505
303
-static noinline void __init kmalloc_uaf_memset(void)
506
+static void kmalloc_uaf_memset(struct kunit *test)
304507 {
305508 char *ptr;
306509 size_t size = 33;
307510
308
- pr_info("use-after-free in memset\n");
309511 ptr = kmalloc(size, GFP_KERNEL);
310
- if (!ptr) {
311
- pr_err("Allocation failed\n");
312
- return;
313
- }
512
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
314513
315514 kfree(ptr);
316
- memset(ptr, 0, size);
515
+ KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr, 0, size));
317516 }
318517
319
-static noinline void __init kmalloc_uaf2(void)
518
+static void kmalloc_uaf2(struct kunit *test)
320519 {
321520 char *ptr1, *ptr2;
322521 size_t size = 43;
522
+ int counter = 0;
323523
324
- pr_info("use-after-free after another kmalloc\n");
524
+again:
325525 ptr1 = kmalloc(size, GFP_KERNEL);
326
- if (!ptr1) {
327
- pr_err("Allocation failed\n");
328
- return;
329
- }
526
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1);
330527
331528 kfree(ptr1);
529
+
332530 ptr2 = kmalloc(size, GFP_KERNEL);
333
- if (!ptr2) {
334
- pr_err("Allocation failed\n");
335
- return;
531
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
532
+
533
+ /*
534
+ * For tag-based KASAN ptr1 and ptr2 tags might happen to be the same.
535
+ * Allow up to 16 attempts at generating different tags.
536
+ */
537
+ if (!IS_ENABLED(CONFIG_KASAN_GENERIC) && ptr1 == ptr2 && counter++ < 16) {
538
+ kfree(ptr2);
539
+ goto again;
336540 }
337541
338
- ptr1[40] = 'x';
339
- if (ptr1 == ptr2)
340
- pr_err("Could not detect use-after-free: ptr1 == ptr2\n");
542
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr1[40] = 'x');
543
+ KUNIT_EXPECT_PTR_NE(test, ptr1, ptr2);
544
+
341545 kfree(ptr2);
342546 }
343547
344
-static noinline void __init kmem_cache_oob(void)
548
+static void kfree_via_page(struct kunit *test)
549
+{
550
+ char *ptr;
551
+ size_t size = 8;
552
+ struct page *page;
553
+ unsigned long offset;
554
+
555
+ ptr = kmalloc(size, GFP_KERNEL);
556
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
557
+
558
+ page = virt_to_page(ptr);
559
+ offset = offset_in_page(ptr);
560
+ kfree(page_address(page) + offset);
561
+}
562
+
563
+static void kfree_via_phys(struct kunit *test)
564
+{
565
+ char *ptr;
566
+ size_t size = 8;
567
+ phys_addr_t phys;
568
+
569
+ ptr = kmalloc(size, GFP_KERNEL);
570
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
571
+
572
+ phys = virt_to_phys(ptr);
573
+ kfree(phys_to_virt(phys));
574
+}
575
+
576
+static void kmem_cache_oob(struct kunit *test)
345577 {
346578 char *p;
347579 size_t size = 200;
348
- struct kmem_cache *cache = kmem_cache_create("test_cache",
349
- size, 0,
350
- 0, NULL);
351
- if (!cache) {
352
- pr_err("Cache allocation failed\n");
353
- return;
354
- }
355
- pr_info("out-of-bounds in kmem_cache_alloc\n");
580
+ struct kmem_cache *cache;
581
+
582
+ cache = kmem_cache_create("test_cache", size, 0, 0, NULL);
583
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache);
584
+
356585 p = kmem_cache_alloc(cache, GFP_KERNEL);
357586 if (!p) {
358
- pr_err("Allocation failed\n");
587
+ kunit_err(test, "Allocation failed: %s\n", __func__);
359588 kmem_cache_destroy(cache);
360589 return;
361590 }
362591
363
- *p = p[size];
592
+ KUNIT_EXPECT_KASAN_FAIL(test, *p = p[size + OOB_TAG_OFF]);
593
+
364594 kmem_cache_free(cache, p);
365595 kmem_cache_destroy(cache);
366596 }
367597
368
-static noinline void __init memcg_accounted_kmem_cache(void)
598
+static void kmem_cache_accounted(struct kunit *test)
369599 {
370600 int i;
371601 char *p;
....@@ -373,12 +603,8 @@
373603 struct kmem_cache *cache;
374604
375605 cache = kmem_cache_create("test_cache", size, 0, SLAB_ACCOUNT, NULL);
376
- if (!cache) {
377
- pr_err("Cache allocation failed\n");
378
- return;
379
- }
606
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache);
380607
381
- pr_info("allocate memcg accounted object\n");
382608 /*
383609 * Several allocations with a delay to allow for lazy per memcg kmem
384610 * cache creation.
....@@ -396,136 +622,157 @@
396622 kmem_cache_destroy(cache);
397623 }
398624
625
+static void kmem_cache_bulk(struct kunit *test)
626
+{
627
+ struct kmem_cache *cache;
628
+ size_t size = 200;
629
+ char *p[10];
630
+ bool ret;
631
+ int i;
632
+
633
+ cache = kmem_cache_create("test_cache", size, 0, 0, NULL);
634
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache);
635
+
636
+ ret = kmem_cache_alloc_bulk(cache, GFP_KERNEL, ARRAY_SIZE(p), (void **)&p);
637
+ if (!ret) {
638
+ kunit_err(test, "Allocation failed: %s\n", __func__);
639
+ kmem_cache_destroy(cache);
640
+ return;
641
+ }
642
+
643
+ for (i = 0; i < ARRAY_SIZE(p); i++)
644
+ p[i][0] = p[i][size - 1] = 42;
645
+
646
+ kmem_cache_free_bulk(cache, ARRAY_SIZE(p), (void **)&p);
647
+ kmem_cache_destroy(cache);
648
+}
649
+
399650 static char global_array[10];
400651
401
-static noinline void __init kasan_global_oob(void)
652
+static void kasan_global_oob(struct kunit *test)
402653 {
403
- volatile int i = 3;
404
- char *p = &global_array[ARRAY_SIZE(global_array) + i];
654
+ /*
655
+ * Deliberate out-of-bounds access. To prevent CONFIG_UBSAN_LOCAL_BOUNDS
656
+ * from failing here and panicing the kernel, access the array via a
657
+ * volatile pointer, which will prevent the compiler from being able to
658
+ * determine the array bounds.
659
+ *
660
+ * This access uses a volatile pointer to char (char *volatile) rather
661
+ * than the more conventional pointer to volatile char (volatile char *)
662
+ * because we want to prevent the compiler from making inferences about
663
+ * the pointer itself (i.e. its array bounds), not the data that it
664
+ * refers to.
665
+ */
666
+ char *volatile array = global_array;
667
+ char *p = &array[ARRAY_SIZE(global_array) + 3];
405668
406
- pr_info("out-of-bounds global variable\n");
407
- *(volatile char *)p;
669
+ /* Only generic mode instruments globals. */
670
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_GENERIC);
671
+
672
+ KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p);
408673 }
409674
410
-static noinline void __init kasan_stack_oob(void)
411
-{
412
- char stack_array[10];
413
- volatile int i = 0;
414
- char *p = &stack_array[ARRAY_SIZE(stack_array) + i];
415
-
416
- pr_info("out-of-bounds on stack\n");
417
- *(volatile char *)p;
418
-}
419
-
420
-static noinline void __init ksize_unpoisons_memory(void)
675
+/* Check that ksize() makes the whole object accessible. */
676
+static void ksize_unpoisons_memory(struct kunit *test)
421677 {
422678 char *ptr;
423679 size_t size = 123, real_size;
424680
425
- pr_info("ksize() unpoisons the whole allocated chunk\n");
426681 ptr = kmalloc(size, GFP_KERNEL);
427
- if (!ptr) {
428
- pr_err("Allocation failed\n");
429
- return;
430
- }
682
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
431683 real_size = ksize(ptr);
432
- /* This access doesn't trigger an error. */
684
+
685
+ /* This access shouldn't trigger a KASAN report. */
433686 ptr[size] = 'x';
434
- /* This one does. */
435
- ptr[real_size] = 'y';
687
+
688
+ /* This one must. */
689
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[real_size] = 'y');
690
+
436691 kfree(ptr);
437692 }
438693
439
-static noinline void __init copy_user_test(void)
694
+/*
695
+ * Check that a use-after-free is detected by ksize() and via normal accesses
696
+ * after it.
697
+ */
698
+static void ksize_uaf(struct kunit *test)
440699 {
441
- char *kmem;
442
- char __user *usermem;
443
- size_t size = 10;
444
- int unused;
700
+ char *ptr;
701
+ int size = 128 - KASAN_GRANULE_SIZE;
445702
446
- kmem = kmalloc(size, GFP_KERNEL);
447
- if (!kmem)
448
- return;
703
+ ptr = kmalloc(size, GFP_KERNEL);
704
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
705
+ kfree(ptr);
449706
450
- usermem = (char __user *)vm_mmap(NULL, 0, PAGE_SIZE,
451
- PROT_READ | PROT_WRITE | PROT_EXEC,
452
- MAP_ANONYMOUS | MAP_PRIVATE, 0);
453
- if (IS_ERR(usermem)) {
454
- pr_err("Failed to allocate user memory\n");
455
- kfree(kmem);
456
- return;
457
- }
458
-
459
- pr_info("out-of-bounds in copy_from_user()\n");
460
- unused = copy_from_user(kmem, usermem, size + 1);
461
-
462
- pr_info("out-of-bounds in copy_to_user()\n");
463
- unused = copy_to_user(usermem, kmem, size + 1);
464
-
465
- pr_info("out-of-bounds in __copy_from_user()\n");
466
- unused = __copy_from_user(kmem, usermem, size + 1);
467
-
468
- pr_info("out-of-bounds in __copy_to_user()\n");
469
- unused = __copy_to_user(usermem, kmem, size + 1);
470
-
471
- pr_info("out-of-bounds in __copy_from_user_inatomic()\n");
472
- unused = __copy_from_user_inatomic(kmem, usermem, size + 1);
473
-
474
- pr_info("out-of-bounds in __copy_to_user_inatomic()\n");
475
- unused = __copy_to_user_inatomic(usermem, kmem, size + 1);
476
-
477
- pr_info("out-of-bounds in strncpy_from_user()\n");
478
- unused = strncpy_from_user(kmem, usermem, size + 1);
479
-
480
- vm_munmap((unsigned long)usermem, PAGE_SIZE);
481
- kfree(kmem);
707
+ KUNIT_EXPECT_KASAN_FAIL(test, ksize(ptr));
708
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = *ptr);
709
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = *(ptr + size));
482710 }
483711
484
-static noinline void __init kasan_alloca_oob_left(void)
712
+static void kasan_stack_oob(struct kunit *test)
713
+{
714
+ char stack_array[10];
715
+ /* See comment in kasan_global_oob. */
716
+ char *volatile array = stack_array;
717
+ char *p = &array[ARRAY_SIZE(stack_array) + OOB_TAG_OFF];
718
+
719
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_STACK);
720
+
721
+ KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p);
722
+}
723
+
724
+static void kasan_alloca_oob_left(struct kunit *test)
485725 {
486726 volatile int i = 10;
487727 char alloca_array[i];
488
- char *p = alloca_array - 1;
728
+ /* See comment in kasan_global_oob. */
729
+ char *volatile array = alloca_array;
730
+ char *p = array - 1;
489731
490
- pr_info("out-of-bounds to left on alloca\n");
491
- *(volatile char *)p;
732
+ /* Only generic mode instruments dynamic allocas. */
733
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_GENERIC);
734
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_STACK);
735
+
736
+ KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p);
492737 }
493738
494
-static noinline void __init kasan_alloca_oob_right(void)
739
+static void kasan_alloca_oob_right(struct kunit *test)
495740 {
496741 volatile int i = 10;
497742 char alloca_array[i];
498
- char *p = alloca_array + i;
743
+ /* See comment in kasan_global_oob. */
744
+ char *volatile array = alloca_array;
745
+ char *p = array + i;
499746
500
- pr_info("out-of-bounds to right on alloca\n");
501
- *(volatile char *)p;
747
+ /* Only generic mode instruments dynamic allocas. */
748
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_GENERIC);
749
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_STACK);
750
+
751
+ KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p);
502752 }
503753
504
-static noinline void __init kmem_cache_double_free(void)
754
+static void kmem_cache_double_free(struct kunit *test)
505755 {
506756 char *p;
507757 size_t size = 200;
508758 struct kmem_cache *cache;
509759
510760 cache = kmem_cache_create("test_cache", size, 0, 0, NULL);
511
- if (!cache) {
512
- pr_err("Cache allocation failed\n");
513
- return;
514
- }
515
- pr_info("double-free on heap object\n");
761
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache);
762
+
516763 p = kmem_cache_alloc(cache, GFP_KERNEL);
517764 if (!p) {
518
- pr_err("Allocation failed\n");
765
+ kunit_err(test, "Allocation failed: %s\n", __func__);
519766 kmem_cache_destroy(cache);
520767 return;
521768 }
522769
523770 kmem_cache_free(cache, p);
524
- kmem_cache_free(cache, p);
771
+ KUNIT_EXPECT_KASAN_FAIL(test, kmem_cache_free(cache, p));
525772 kmem_cache_destroy(cache);
526773 }
527774
528
-static noinline void __init kmem_cache_invalid_free(void)
775
+static void kmem_cache_invalid_free(struct kunit *test)
529776 {
530777 char *p;
531778 size_t size = 200;
....@@ -533,20 +780,17 @@
533780
534781 cache = kmem_cache_create("test_cache", size, 0, SLAB_TYPESAFE_BY_RCU,
535782 NULL);
536
- if (!cache) {
537
- pr_err("Cache allocation failed\n");
538
- return;
539
- }
540
- pr_info("invalid-free of heap object\n");
783
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache);
784
+
541785 p = kmem_cache_alloc(cache, GFP_KERNEL);
542786 if (!p) {
543
- pr_err("Allocation failed\n");
787
+ kunit_err(test, "Allocation failed: %s\n", __func__);
544788 kmem_cache_destroy(cache);
545789 return;
546790 }
547791
548
- /* Trigger invalid free, the object doesn't get freed */
549
- kmem_cache_free(cache, p + 1);
792
+ /* Trigger invalid free, the object doesn't get freed. */
793
+ KUNIT_EXPECT_KASAN_FAIL(test, kmem_cache_free(cache, p + 1));
550794
551795 /*
552796 * Properly free the object to prevent the "Objects remaining in
....@@ -557,45 +801,66 @@
557801 kmem_cache_destroy(cache);
558802 }
559803
560
-static noinline void __init kasan_memchr(void)
804
+static void kasan_memchr(struct kunit *test)
561805 {
562806 char *ptr;
563807 size_t size = 24;
564808
565
- pr_info("out-of-bounds in memchr\n");
566
- ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
567
- if (!ptr)
568
- return;
809
+ /*
810
+ * str* functions are not instrumented with CONFIG_AMD_MEM_ENCRYPT.
811
+ * See https://bugzilla.kernel.org/show_bug.cgi?id=206337 for details.
812
+ */
813
+ KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_AMD_MEM_ENCRYPT);
569814
570
- memchr(ptr, '1', size + 1);
815
+ if (OOB_TAG_OFF)
816
+ size = round_up(size, OOB_TAG_OFF);
817
+
818
+ ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
819
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
820
+
821
+ KUNIT_EXPECT_KASAN_FAIL(test,
822
+ kasan_ptr_result = memchr(ptr, '1', size + 1));
823
+
571824 kfree(ptr);
572825 }
573826
574
-static noinline void __init kasan_memcmp(void)
827
+static void kasan_memcmp(struct kunit *test)
575828 {
576829 char *ptr;
577830 size_t size = 24;
578831 int arr[9];
579832
580
- pr_info("out-of-bounds in memcmp\n");
581
- ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
582
- if (!ptr)
583
- return;
833
+ /*
834
+ * str* functions are not instrumented with CONFIG_AMD_MEM_ENCRYPT.
835
+ * See https://bugzilla.kernel.org/show_bug.cgi?id=206337 for details.
836
+ */
837
+ KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_AMD_MEM_ENCRYPT);
584838
839
+ if (OOB_TAG_OFF)
840
+ size = round_up(size, OOB_TAG_OFF);
841
+
842
+ ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
843
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
585844 memset(arr, 0, sizeof(arr));
586
- memcmp(ptr, arr, size+1);
845
+
846
+ KUNIT_EXPECT_KASAN_FAIL(test,
847
+ kasan_int_result = memcmp(ptr, arr, size+1));
587848 kfree(ptr);
588849 }
589850
590
-static noinline void __init kasan_strings(void)
851
+static void kasan_strings(struct kunit *test)
591852 {
592853 char *ptr;
593854 size_t size = 24;
594855
595
- pr_info("use-after-free in strchr\n");
856
+ /*
857
+ * str* functions are not instrumented with CONFIG_AMD_MEM_ENCRYPT.
858
+ * See https://bugzilla.kernel.org/show_bug.cgi?id=206337 for details.
859
+ */
860
+ KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_AMD_MEM_ENCRYPT);
861
+
596862 ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
597
- if (!ptr)
598
- return;
863
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
599864
600865 kfree(ptr);
601866
....@@ -606,70 +871,271 @@
606871 * will likely point to zeroed byte.
607872 */
608873 ptr += 16;
609
- strchr(ptr, '1');
874
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_ptr_result = strchr(ptr, '1'));
610875
611
- pr_info("use-after-free in strrchr\n");
612
- strrchr(ptr, '1');
876
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_ptr_result = strrchr(ptr, '1'));
613877
614
- pr_info("use-after-free in strcmp\n");
615
- strcmp(ptr, "2");
878
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = strcmp(ptr, "2"));
616879
617
- pr_info("use-after-free in strncmp\n");
618
- strncmp(ptr, "2", 1);
880
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = strncmp(ptr, "2", 1));
619881
620
- pr_info("use-after-free in strlen\n");
621
- strlen(ptr);
882
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = strlen(ptr));
622883
623
- pr_info("use-after-free in strnlen\n");
624
- strnlen(ptr, 1);
884
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = strnlen(ptr, 1));
625885 }
626886
627
-static int __init kmalloc_tests_init(void)
887
+static void kasan_bitops_modify(struct kunit *test, int nr, void *addr)
628888 {
629
- /*
630
- * Temporarily enable multi-shot mode. Otherwise, we'd only get a
631
- * report for the first case.
632
- */
633
- bool multishot = kasan_save_enable_multi_shot();
634
-
635
- kmalloc_oob_right();
636
- kmalloc_oob_left();
637
- kmalloc_node_oob_right();
638
-#ifdef CONFIG_SLUB
639
- kmalloc_pagealloc_oob_right();
640
- kmalloc_pagealloc_uaf();
641
- kmalloc_pagealloc_invalid_free();
642
-#endif
643
- kmalloc_large_oob_right();
644
- kmalloc_oob_krealloc_more();
645
- kmalloc_oob_krealloc_less();
646
- kmalloc_oob_16();
647
- kmalloc_oob_in_memset();
648
- kmalloc_oob_memset_2();
649
- kmalloc_oob_memset_4();
650
- kmalloc_oob_memset_8();
651
- kmalloc_oob_memset_16();
652
- kmalloc_uaf();
653
- kmalloc_uaf_memset();
654
- kmalloc_uaf2();
655
- kmem_cache_oob();
656
- memcg_accounted_kmem_cache();
657
- kasan_stack_oob();
658
- kasan_global_oob();
659
- kasan_alloca_oob_left();
660
- kasan_alloca_oob_right();
661
- ksize_unpoisons_memory();
662
- copy_user_test();
663
- kmem_cache_double_free();
664
- kmem_cache_invalid_free();
665
- kasan_memchr();
666
- kasan_memcmp();
667
- kasan_strings();
668
-
669
- kasan_restore_multi_shot(multishot);
670
-
671
- return -EAGAIN;
889
+ KUNIT_EXPECT_KASAN_FAIL(test, set_bit(nr, addr));
890
+ KUNIT_EXPECT_KASAN_FAIL(test, __set_bit(nr, addr));
891
+ KUNIT_EXPECT_KASAN_FAIL(test, clear_bit(nr, addr));
892
+ KUNIT_EXPECT_KASAN_FAIL(test, __clear_bit(nr, addr));
893
+ KUNIT_EXPECT_KASAN_FAIL(test, clear_bit_unlock(nr, addr));
894
+ KUNIT_EXPECT_KASAN_FAIL(test, __clear_bit_unlock(nr, addr));
895
+ KUNIT_EXPECT_KASAN_FAIL(test, change_bit(nr, addr));
896
+ KUNIT_EXPECT_KASAN_FAIL(test, __change_bit(nr, addr));
672897 }
673898
674
-module_init(kmalloc_tests_init);
899
+static void kasan_bitops_test_and_modify(struct kunit *test, int nr, void *addr)
900
+{
901
+ KUNIT_EXPECT_KASAN_FAIL(test, test_and_set_bit(nr, addr));
902
+ KUNIT_EXPECT_KASAN_FAIL(test, __test_and_set_bit(nr, addr));
903
+ KUNIT_EXPECT_KASAN_FAIL(test, test_and_set_bit_lock(nr, addr));
904
+ KUNIT_EXPECT_KASAN_FAIL(test, test_and_clear_bit(nr, addr));
905
+ KUNIT_EXPECT_KASAN_FAIL(test, __test_and_clear_bit(nr, addr));
906
+ KUNIT_EXPECT_KASAN_FAIL(test, test_and_change_bit(nr, addr));
907
+ KUNIT_EXPECT_KASAN_FAIL(test, __test_and_change_bit(nr, addr));
908
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result = test_bit(nr, addr));
909
+
910
+#if defined(clear_bit_unlock_is_negative_byte)
911
+ KUNIT_EXPECT_KASAN_FAIL(test, kasan_int_result =
912
+ clear_bit_unlock_is_negative_byte(nr, addr));
913
+#endif
914
+}
915
+
916
+static void kasan_bitops_generic(struct kunit *test)
917
+{
918
+ long *bits;
919
+
920
+ /* This test is specifically crafted for the generic mode. */
921
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_GENERIC);
922
+
923
+ /*
924
+ * Allocate 1 more byte, which causes kzalloc to round up to 16 bytes;
925
+ * this way we do not actually corrupt other memory.
926
+ */
927
+ bits = kzalloc(sizeof(*bits) + 1, GFP_KERNEL);
928
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bits);
929
+
930
+ /*
931
+ * Below calls try to access bit within allocated memory; however, the
932
+ * below accesses are still out-of-bounds, since bitops are defined to
933
+ * operate on the whole long the bit is in.
934
+ */
935
+ kasan_bitops_modify(test, BITS_PER_LONG, bits);
936
+
937
+ /*
938
+ * Below calls try to access bit beyond allocated memory.
939
+ */
940
+ kasan_bitops_test_and_modify(test, BITS_PER_LONG + BITS_PER_BYTE, bits);
941
+
942
+ kfree(bits);
943
+}
944
+
945
+static void kasan_bitops_tags(struct kunit *test)
946
+{
947
+ long *bits;
948
+
949
+ /* This test is specifically crafted for tag-based modes. */
950
+ KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_KASAN_GENERIC);
951
+
952
+ /* kmalloc-64 cache will be used and the last 16 bytes will be the redzone. */
953
+ bits = kzalloc(48, GFP_KERNEL);
954
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bits);
955
+
956
+ /* Do the accesses past the 48 allocated bytes, but within the redone. */
957
+ kasan_bitops_modify(test, BITS_PER_LONG, (void *)bits + 48);
958
+ kasan_bitops_test_and_modify(test, BITS_PER_LONG + BITS_PER_BYTE, (void *)bits + 48);
959
+
960
+ kfree(bits);
961
+}
962
+
963
+static void kmalloc_double_kzfree(struct kunit *test)
964
+{
965
+ char *ptr;
966
+ size_t size = 16;
967
+
968
+ ptr = kmalloc(size, GFP_KERNEL);
969
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
970
+
971
+ kfree_sensitive(ptr);
972
+ KUNIT_EXPECT_KASAN_FAIL(test, kfree_sensitive(ptr));
973
+}
974
+
975
+static void vmalloc_oob(struct kunit *test)
976
+{
977
+ void *area;
978
+
979
+ KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_VMALLOC);
980
+
981
+ /*
982
+ * We have to be careful not to hit the guard page.
983
+ * The MMU will catch that and crash us.
984
+ */
985
+ area = vmalloc(3000);
986
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, area);
987
+
988
+ KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)area)[3100]);
989
+ vfree(area);
990
+}
991
+
992
+/*
993
+ * Check that the assigned pointer tag falls within the [KASAN_TAG_MIN,
994
+ * KASAN_TAG_KERNEL) range (note: excluding the match-all tag) for tag-based
995
+ * modes.
996
+ */
997
+static void match_all_not_assigned(struct kunit *test)
998
+{
999
+ char *ptr;
1000
+ struct page *pages;
1001
+ int i, size, order;
1002
+
1003
+ KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_KASAN_GENERIC);
1004
+
1005
+ for (i = 0; i < 256; i++) {
1006
+ size = (get_random_int() % 1024) + 1;
1007
+ ptr = kmalloc(size, GFP_KERNEL);
1008
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
1009
+ KUNIT_EXPECT_GE(test, (u8)get_tag(ptr), (u8)KASAN_TAG_MIN);
1010
+ KUNIT_EXPECT_LT(test, (u8)get_tag(ptr), (u8)KASAN_TAG_KERNEL);
1011
+ kfree(ptr);
1012
+ }
1013
+
1014
+ for (i = 0; i < 256; i++) {
1015
+ order = (get_random_int() % 4) + 1;
1016
+ pages = alloc_pages(GFP_KERNEL, order);
1017
+ ptr = page_address(pages);
1018
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
1019
+ KUNIT_EXPECT_GE(test, (u8)get_tag(ptr), (u8)KASAN_TAG_MIN);
1020
+ KUNIT_EXPECT_LT(test, (u8)get_tag(ptr), (u8)KASAN_TAG_KERNEL);
1021
+ free_pages((unsigned long)ptr, order);
1022
+ }
1023
+}
1024
+
1025
+/* Check that 0xff works as a match-all pointer tag for tag-based modes. */
1026
+static void match_all_ptr_tag(struct kunit *test)
1027
+{
1028
+ char *ptr;
1029
+ u8 tag;
1030
+
1031
+ KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_KASAN_GENERIC);
1032
+
1033
+ ptr = kmalloc(128, GFP_KERNEL);
1034
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
1035
+
1036
+ /* Backup the assigned tag. */
1037
+ tag = get_tag(ptr);
1038
+ KUNIT_EXPECT_NE(test, tag, (u8)KASAN_TAG_KERNEL);
1039
+
1040
+ /* Reset the tag to 0xff.*/
1041
+ ptr = set_tag(ptr, KASAN_TAG_KERNEL);
1042
+
1043
+ /* This access shouldn't trigger a KASAN report. */
1044
+ *ptr = 0;
1045
+
1046
+ /* Recover the pointer tag and free. */
1047
+ ptr = set_tag(ptr, tag);
1048
+ kfree(ptr);
1049
+}
1050
+
1051
+/* Check that there are no match-all memory tags for tag-based modes. */
1052
+static void match_all_mem_tag(struct kunit *test)
1053
+{
1054
+ char *ptr;
1055
+ int tag;
1056
+
1057
+ KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_KASAN_GENERIC);
1058
+
1059
+ ptr = kmalloc(128, GFP_KERNEL);
1060
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
1061
+ KUNIT_EXPECT_NE(test, (u8)get_tag(ptr), (u8)KASAN_TAG_KERNEL);
1062
+
1063
+ /* For each possible tag value not matching the pointer tag. */
1064
+ for (tag = KASAN_TAG_MIN; tag <= KASAN_TAG_KERNEL; tag++) {
1065
+ if (tag == get_tag(ptr))
1066
+ continue;
1067
+
1068
+ /* Mark the first memory granule with the chosen memory tag. */
1069
+ kasan_poison(ptr, KASAN_GRANULE_SIZE, (u8)tag, false);
1070
+
1071
+ /* This access must cause a KASAN report. */
1072
+ KUNIT_EXPECT_KASAN_FAIL(test, *ptr = 0);
1073
+ }
1074
+
1075
+ /* Recover the memory tag and free. */
1076
+ kasan_poison(ptr, KASAN_GRANULE_SIZE, get_tag(ptr), false);
1077
+ kfree(ptr);
1078
+}
1079
+
1080
+static struct kunit_case kasan_kunit_test_cases[] = {
1081
+ KUNIT_CASE(kmalloc_oob_right),
1082
+ KUNIT_CASE(kmalloc_oob_left),
1083
+ KUNIT_CASE(kmalloc_node_oob_right),
1084
+ KUNIT_CASE(kmalloc_pagealloc_oob_right),
1085
+ KUNIT_CASE(kmalloc_pagealloc_uaf),
1086
+ KUNIT_CASE(kmalloc_pagealloc_invalid_free),
1087
+ KUNIT_CASE(pagealloc_oob_right),
1088
+ KUNIT_CASE(pagealloc_uaf),
1089
+ KUNIT_CASE(kmalloc_large_oob_right),
1090
+ KUNIT_CASE(krealloc_more_oob),
1091
+ KUNIT_CASE(krealloc_less_oob),
1092
+ KUNIT_CASE(krealloc_pagealloc_more_oob),
1093
+ KUNIT_CASE(krealloc_pagealloc_less_oob),
1094
+ KUNIT_CASE(krealloc_uaf),
1095
+ KUNIT_CASE(kmalloc_oob_16),
1096
+ KUNIT_CASE(kmalloc_uaf_16),
1097
+ KUNIT_CASE(kmalloc_oob_in_memset),
1098
+ KUNIT_CASE(kmalloc_oob_memset_2),
1099
+ KUNIT_CASE(kmalloc_oob_memset_4),
1100
+ KUNIT_CASE(kmalloc_oob_memset_8),
1101
+ KUNIT_CASE(kmalloc_oob_memset_16),
1102
+ KUNIT_CASE(kmalloc_memmove_invalid_size),
1103
+ KUNIT_CASE(kmalloc_uaf),
1104
+ KUNIT_CASE(kmalloc_uaf_memset),
1105
+ KUNIT_CASE(kmalloc_uaf2),
1106
+ KUNIT_CASE(kfree_via_page),
1107
+ KUNIT_CASE(kfree_via_phys),
1108
+ KUNIT_CASE(kmem_cache_oob),
1109
+ KUNIT_CASE(kmem_cache_accounted),
1110
+ KUNIT_CASE(kmem_cache_bulk),
1111
+ KUNIT_CASE(kasan_global_oob),
1112
+ KUNIT_CASE(kasan_stack_oob),
1113
+ KUNIT_CASE(kasan_alloca_oob_left),
1114
+ KUNIT_CASE(kasan_alloca_oob_right),
1115
+ KUNIT_CASE(ksize_unpoisons_memory),
1116
+ KUNIT_CASE(ksize_uaf),
1117
+ KUNIT_CASE(kmem_cache_double_free),
1118
+ KUNIT_CASE(kmem_cache_invalid_free),
1119
+ KUNIT_CASE(kasan_memchr),
1120
+ KUNIT_CASE(kasan_memcmp),
1121
+ KUNIT_CASE(kasan_strings),
1122
+ KUNIT_CASE(kasan_bitops_generic),
1123
+ KUNIT_CASE(kasan_bitops_tags),
1124
+ KUNIT_CASE(kmalloc_double_kzfree),
1125
+ KUNIT_CASE(vmalloc_oob),
1126
+ KUNIT_CASE(match_all_not_assigned),
1127
+ KUNIT_CASE(match_all_ptr_tag),
1128
+ KUNIT_CASE(match_all_mem_tag),
1129
+ {}
1130
+};
1131
+
1132
+static struct kunit_suite kasan_kunit_test_suite = {
1133
+ .name = "kasan",
1134
+ .init = kasan_test_init,
1135
+ .test_cases = kasan_kunit_test_cases,
1136
+ .exit = kasan_test_exit,
1137
+};
1138
+
1139
+kunit_test_suite(kasan_kunit_test_suite);
1140
+
6751141 MODULE_LICENSE("GPL");