KUnit: KASAN Integration
[linux-2.6-microblaze.git] / lib / test_kasan.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5  * Author: Andrey Ryabinin <a.ryabinin@samsung.com>
6  */
7
8 #define pr_fmt(fmt) "kasan test: %s " fmt, __func__
9
10 #include <linux/bitops.h>
11 #include <linux/delay.h>
12 #include <linux/kasan.h>
13 #include <linux/kernel.h>
14 #include <linux/mm.h>
15 #include <linux/mman.h>
16 #include <linux/module.h>
17 #include <linux/printk.h>
18 #include <linux/slab.h>
19 #include <linux/string.h>
20 #include <linux/uaccess.h>
21 #include <linux/io.h>
22 #include <linux/vmalloc.h>
23
24 #include <asm/page.h>
25
26 #include <kunit/test.h>
27
28 #include "../mm/kasan/kasan.h"
29
30 #define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_SHADOW_SCALE_SIZE)
31
32 /*
33  * We assign some test results to these globals to make sure the tests
34  * are not eliminated as dead code.
35  */
36
37 void *kasan_ptr_result;
38 int kasan_int_result;
39
40 static struct kunit_resource resource;
41 static struct kunit_kasan_expectation fail_data;
42 static bool multishot;
43
44 static int kasan_test_init(struct kunit *test)
45 {
46         /*
47          * Temporarily enable multi-shot mode and set panic_on_warn=0.
48          * Otherwise, we'd only get a report for the first case.
49          */
50         multishot = kasan_save_enable_multi_shot();
51
52         return 0;
53 }
54
55 static void kasan_test_exit(struct kunit *test)
56 {
57         kasan_restore_multi_shot(multishot);
58 }
59
60 /**
61  * KUNIT_EXPECT_KASAN_FAIL() - Causes a test failure when the expression does
62  * not cause a KASAN error. This uses a KUnit resource named "kasan_data." Do
63  * Do not use this name for a KUnit resource outside here.
64  *
65  */
66 #define KUNIT_EXPECT_KASAN_FAIL(test, condition) do { \
67         fail_data.report_expected = true; \
68         fail_data.report_found = false; \
69         kunit_add_named_resource(test, \
70                                 NULL, \
71                                 NULL, \
72                                 &resource, \
73                                 "kasan_data", &fail_data); \
74         condition; \
75         KUNIT_EXPECT_EQ(test, \
76                         fail_data.report_expected, \
77                         fail_data.report_found); \
78 } while (0)
79
80
81
82 /*
83  * Note: test functions are marked noinline so that their names appear in
84  * reports.
85  */
86 static noinline void __init kmalloc_oob_right(void)
87 {
88         char *ptr;
89         size_t size = 123;
90
91         pr_info("out-of-bounds to right\n");
92         ptr = kmalloc(size, GFP_KERNEL);
93         if (!ptr) {
94                 pr_err("Allocation failed\n");
95                 return;
96         }
97
98         ptr[size + OOB_TAG_OFF] = 'x';
99
100         kfree(ptr);
101 }
102
103 static noinline void __init kmalloc_oob_left(void)
104 {
105         char *ptr;
106         size_t size = 15;
107
108         pr_info("out-of-bounds to left\n");
109         ptr = kmalloc(size, GFP_KERNEL);
110         if (!ptr) {
111                 pr_err("Allocation failed\n");
112                 return;
113         }
114
115         *ptr = *(ptr - 1);
116         kfree(ptr);
117 }
118
119 static noinline void __init kmalloc_node_oob_right(void)
120 {
121         char *ptr;
122         size_t size = 4096;
123
124         pr_info("kmalloc_node(): out-of-bounds to right\n");
125         ptr = kmalloc_node(size, GFP_KERNEL, 0);
126         if (!ptr) {
127                 pr_err("Allocation failed\n");
128                 return;
129         }
130
131         ptr[size] = 0;
132         kfree(ptr);
133 }
134
135 #ifdef CONFIG_SLUB
136 static noinline void __init kmalloc_pagealloc_oob_right(void)
137 {
138         char *ptr;
139         size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
140
141         /* Allocate a chunk that does not fit into a SLUB cache to trigger
142          * the page allocator fallback.
143          */
144         pr_info("kmalloc pagealloc allocation: out-of-bounds to right\n");
145         ptr = kmalloc(size, GFP_KERNEL);
146         if (!ptr) {
147                 pr_err("Allocation failed\n");
148                 return;
149         }
150
151         ptr[size + OOB_TAG_OFF] = 0;
152
153         kfree(ptr);
154 }
155
156 static noinline void __init kmalloc_pagealloc_uaf(void)
157 {
158         char *ptr;
159         size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
160
161         pr_info("kmalloc pagealloc allocation: use-after-free\n");
162         ptr = kmalloc(size, GFP_KERNEL);
163         if (!ptr) {
164                 pr_err("Allocation failed\n");
165                 return;
166         }
167
168         kfree(ptr);
169         ptr[0] = 0;
170 }
171
172 static noinline void __init kmalloc_pagealloc_invalid_free(void)
173 {
174         char *ptr;
175         size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
176
177         pr_info("kmalloc pagealloc allocation: invalid-free\n");
178         ptr = kmalloc(size, GFP_KERNEL);
179         if (!ptr) {
180                 pr_err("Allocation failed\n");
181                 return;
182         }
183
184         kfree(ptr + 1);
185 }
186 #endif
187
188 static noinline void __init kmalloc_large_oob_right(void)
189 {
190         char *ptr;
191         size_t size = KMALLOC_MAX_CACHE_SIZE - 256;
192         /* Allocate a chunk that is large enough, but still fits into a slab
193          * and does not trigger the page allocator fallback in SLUB.
194          */
195         pr_info("kmalloc large allocation: out-of-bounds to right\n");
196         ptr = kmalloc(size, GFP_KERNEL);
197         if (!ptr) {
198                 pr_err("Allocation failed\n");
199                 return;
200         }
201
202         ptr[size] = 0;
203         kfree(ptr);
204 }
205
206 static noinline void __init kmalloc_oob_krealloc_more(void)
207 {
208         char *ptr1, *ptr2;
209         size_t size1 = 17;
210         size_t size2 = 19;
211
212         pr_info("out-of-bounds after krealloc more\n");
213         ptr1 = kmalloc(size1, GFP_KERNEL);
214         ptr2 = krealloc(ptr1, size2, GFP_KERNEL);
215         if (!ptr1 || !ptr2) {
216                 pr_err("Allocation failed\n");
217                 kfree(ptr1);
218                 kfree(ptr2);
219                 return;
220         }
221
222         ptr2[size2 + OOB_TAG_OFF] = 'x';
223
224         kfree(ptr2);
225 }
226
227 static noinline void __init kmalloc_oob_krealloc_less(void)
228 {
229         char *ptr1, *ptr2;
230         size_t size1 = 17;
231         size_t size2 = 15;
232
233         pr_info("out-of-bounds after krealloc less\n");
234         ptr1 = kmalloc(size1, GFP_KERNEL);
235         ptr2 = krealloc(ptr1, size2, GFP_KERNEL);
236         if (!ptr1 || !ptr2) {
237                 pr_err("Allocation failed\n");
238                 kfree(ptr1);
239                 return;
240         }
241
242         ptr2[size2 + OOB_TAG_OFF] = 'x';
243
244         kfree(ptr2);
245 }
246
247 static noinline void __init kmalloc_oob_16(void)
248 {
249         struct {
250                 u64 words[2];
251         } *ptr1, *ptr2;
252
253         pr_info("kmalloc out-of-bounds for 16-bytes access\n");
254         ptr1 = kmalloc(sizeof(*ptr1) - 3, GFP_KERNEL);
255         ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL);
256         if (!ptr1 || !ptr2) {
257                 pr_err("Allocation failed\n");
258                 kfree(ptr1);
259                 kfree(ptr2);
260                 return;
261         }
262         *ptr1 = *ptr2;
263         kfree(ptr1);
264         kfree(ptr2);
265 }
266
267 static noinline void __init kmalloc_oob_memset_2(void)
268 {
269         char *ptr;
270         size_t size = 8;
271
272         pr_info("out-of-bounds in memset2\n");
273         ptr = kmalloc(size, GFP_KERNEL);
274         if (!ptr) {
275                 pr_err("Allocation failed\n");
276                 return;
277         }
278
279         memset(ptr + 7 + OOB_TAG_OFF, 0, 2);
280
281         kfree(ptr);
282 }
283
284 static noinline void __init kmalloc_oob_memset_4(void)
285 {
286         char *ptr;
287         size_t size = 8;
288
289         pr_info("out-of-bounds in memset4\n");
290         ptr = kmalloc(size, GFP_KERNEL);
291         if (!ptr) {
292                 pr_err("Allocation failed\n");
293                 return;
294         }
295
296         memset(ptr + 5 + OOB_TAG_OFF, 0, 4);
297
298         kfree(ptr);
299 }
300
301
302 static noinline void __init kmalloc_oob_memset_8(void)
303 {
304         char *ptr;
305         size_t size = 8;
306
307         pr_info("out-of-bounds in memset8\n");
308         ptr = kmalloc(size, GFP_KERNEL);
309         if (!ptr) {
310                 pr_err("Allocation failed\n");
311                 return;
312         }
313
314         memset(ptr + 1 + OOB_TAG_OFF, 0, 8);
315
316         kfree(ptr);
317 }
318
319 static noinline void __init kmalloc_oob_memset_16(void)
320 {
321         char *ptr;
322         size_t size = 16;
323
324         pr_info("out-of-bounds in memset16\n");
325         ptr = kmalloc(size, GFP_KERNEL);
326         if (!ptr) {
327                 pr_err("Allocation failed\n");
328                 return;
329         }
330
331         memset(ptr + 1 + OOB_TAG_OFF, 0, 16);
332
333         kfree(ptr);
334 }
335
336 static noinline void __init kmalloc_oob_in_memset(void)
337 {
338         char *ptr;
339         size_t size = 666;
340
341         pr_info("out-of-bounds in memset\n");
342         ptr = kmalloc(size, GFP_KERNEL);
343         if (!ptr) {
344                 pr_err("Allocation failed\n");
345                 return;
346         }
347
348         memset(ptr, 0, size + 5 + OOB_TAG_OFF);
349
350         kfree(ptr);
351 }
352
353 static noinline void __init kmalloc_memmove_invalid_size(void)
354 {
355         char *ptr;
356         size_t size = 64;
357         volatile size_t invalid_size = -2;
358
359         pr_info("invalid size in memmove\n");
360         ptr = kmalloc(size, GFP_KERNEL);
361         if (!ptr) {
362                 pr_err("Allocation failed\n");
363                 return;
364         }
365
366         memset((char *)ptr, 0, 64);
367         memmove((char *)ptr, (char *)ptr + 4, invalid_size);
368         kfree(ptr);
369 }
370
371 static noinline void __init kmalloc_uaf(void)
372 {
373         char *ptr;
374         size_t size = 10;
375
376         pr_info("use-after-free\n");
377         ptr = kmalloc(size, GFP_KERNEL);
378         if (!ptr) {
379                 pr_err("Allocation failed\n");
380                 return;
381         }
382
383         kfree(ptr);
384         *(ptr + 8) = 'x';
385 }
386
387 static noinline void __init kmalloc_uaf_memset(void)
388 {
389         char *ptr;
390         size_t size = 33;
391
392         pr_info("use-after-free in memset\n");
393         ptr = kmalloc(size, GFP_KERNEL);
394         if (!ptr) {
395                 pr_err("Allocation failed\n");
396                 return;
397         }
398
399         kfree(ptr);
400         memset(ptr, 0, size);
401 }
402
403 static noinline void __init kmalloc_uaf2(void)
404 {
405         char *ptr1, *ptr2;
406         size_t size = 43;
407
408         pr_info("use-after-free after another kmalloc\n");
409         ptr1 = kmalloc(size, GFP_KERNEL);
410         if (!ptr1) {
411                 pr_err("Allocation failed\n");
412                 return;
413         }
414
415         kfree(ptr1);
416         ptr2 = kmalloc(size, GFP_KERNEL);
417         if (!ptr2) {
418                 pr_err("Allocation failed\n");
419                 return;
420         }
421
422         ptr1[40] = 'x';
423         if (ptr1 == ptr2)
424                 pr_err("Could not detect use-after-free: ptr1 == ptr2\n");
425         kfree(ptr2);
426 }
427
428 static noinline void __init kfree_via_page(void)
429 {
430         char *ptr;
431         size_t size = 8;
432         struct page *page;
433         unsigned long offset;
434
435         pr_info("invalid-free false positive (via page)\n");
436         ptr = kmalloc(size, GFP_KERNEL);
437         if (!ptr) {
438                 pr_err("Allocation failed\n");
439                 return;
440         }
441
442         page = virt_to_page(ptr);
443         offset = offset_in_page(ptr);
444         kfree(page_address(page) + offset);
445 }
446
447 static noinline void __init kfree_via_phys(void)
448 {
449         char *ptr;
450         size_t size = 8;
451         phys_addr_t phys;
452
453         pr_info("invalid-free false positive (via phys)\n");
454         ptr = kmalloc(size, GFP_KERNEL);
455         if (!ptr) {
456                 pr_err("Allocation failed\n");
457                 return;
458         }
459
460         phys = virt_to_phys(ptr);
461         kfree(phys_to_virt(phys));
462 }
463
464 static noinline void __init kmem_cache_oob(void)
465 {
466         char *p;
467         size_t size = 200;
468         struct kmem_cache *cache = kmem_cache_create("test_cache",
469                                                 size, 0,
470                                                 0, NULL);
471         if (!cache) {
472                 pr_err("Cache allocation failed\n");
473                 return;
474         }
475         pr_info("out-of-bounds in kmem_cache_alloc\n");
476         p = kmem_cache_alloc(cache, GFP_KERNEL);
477         if (!p) {
478                 pr_err("Allocation failed\n");
479                 kmem_cache_destroy(cache);
480                 return;
481         }
482
483         *p = p[size + OOB_TAG_OFF];
484
485         kmem_cache_free(cache, p);
486         kmem_cache_destroy(cache);
487 }
488
489 static noinline void __init memcg_accounted_kmem_cache(void)
490 {
491         int i;
492         char *p;
493         size_t size = 200;
494         struct kmem_cache *cache;
495
496         cache = kmem_cache_create("test_cache", size, 0, SLAB_ACCOUNT, NULL);
497         if (!cache) {
498                 pr_err("Cache allocation failed\n");
499                 return;
500         }
501
502         pr_info("allocate memcg accounted object\n");
503         /*
504          * Several allocations with a delay to allow for lazy per memcg kmem
505          * cache creation.
506          */
507         for (i = 0; i < 5; i++) {
508                 p = kmem_cache_alloc(cache, GFP_KERNEL);
509                 if (!p)
510                         goto free_cache;
511
512                 kmem_cache_free(cache, p);
513                 msleep(100);
514         }
515
516 free_cache:
517         kmem_cache_destroy(cache);
518 }
519
520 static char global_array[10];
521
522 static noinline void __init kasan_global_oob(void)
523 {
524         volatile int i = 3;
525         char *p = &global_array[ARRAY_SIZE(global_array) + i];
526
527         pr_info("out-of-bounds global variable\n");
528         *(volatile char *)p;
529 }
530
531 static noinline void __init kasan_stack_oob(void)
532 {
533         char stack_array[10];
534         volatile int i = OOB_TAG_OFF;
535         char *p = &stack_array[ARRAY_SIZE(stack_array) + i];
536
537         pr_info("out-of-bounds on stack\n");
538         *(volatile char *)p;
539 }
540
541 static noinline void __init ksize_unpoisons_memory(void)
542 {
543         char *ptr;
544         size_t size = 123, real_size;
545
546         pr_info("ksize() unpoisons the whole allocated chunk\n");
547         ptr = kmalloc(size, GFP_KERNEL);
548         if (!ptr) {
549                 pr_err("Allocation failed\n");
550                 return;
551         }
552         real_size = ksize(ptr);
553         /* This access doesn't trigger an error. */
554         ptr[size] = 'x';
555         /* This one does. */
556         ptr[real_size] = 'y';
557         kfree(ptr);
558 }
559
560 static noinline void __init copy_user_test(void)
561 {
562         char *kmem;
563         char __user *usermem;
564         size_t size = 10;
565         int unused;
566
567         kmem = kmalloc(size, GFP_KERNEL);
568         if (!kmem)
569                 return;
570
571         usermem = (char __user *)vm_mmap(NULL, 0, PAGE_SIZE,
572                             PROT_READ | PROT_WRITE | PROT_EXEC,
573                             MAP_ANONYMOUS | MAP_PRIVATE, 0);
574         if (IS_ERR(usermem)) {
575                 pr_err("Failed to allocate user memory\n");
576                 kfree(kmem);
577                 return;
578         }
579
580         pr_info("out-of-bounds in copy_from_user()\n");
581         unused = copy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF);
582
583         pr_info("out-of-bounds in copy_to_user()\n");
584         unused = copy_to_user(usermem, kmem, size + 1 + OOB_TAG_OFF);
585
586         pr_info("out-of-bounds in __copy_from_user()\n");
587         unused = __copy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF);
588
589         pr_info("out-of-bounds in __copy_to_user()\n");
590         unused = __copy_to_user(usermem, kmem, size + 1 + OOB_TAG_OFF);
591
592         pr_info("out-of-bounds in __copy_from_user_inatomic()\n");
593         unused = __copy_from_user_inatomic(kmem, usermem, size + 1 + OOB_TAG_OFF);
594
595         pr_info("out-of-bounds in __copy_to_user_inatomic()\n");
596         unused = __copy_to_user_inatomic(usermem, kmem, size + 1 + OOB_TAG_OFF);
597
598         pr_info("out-of-bounds in strncpy_from_user()\n");
599         unused = strncpy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF);
600
601         vm_munmap((unsigned long)usermem, PAGE_SIZE);
602         kfree(kmem);
603 }
604
605 static noinline void __init kasan_alloca_oob_left(void)
606 {
607         volatile int i = 10;
608         char alloca_array[i];
609         char *p = alloca_array - 1;
610
611         pr_info("out-of-bounds to left on alloca\n");
612         *(volatile char *)p;
613 }
614
615 static noinline void __init kasan_alloca_oob_right(void)
616 {
617         volatile int i = 10;
618         char alloca_array[i];
619         char *p = alloca_array + i;
620
621         pr_info("out-of-bounds to right on alloca\n");
622         *(volatile char *)p;
623 }
624
625 static noinline void __init kmem_cache_double_free(void)
626 {
627         char *p;
628         size_t size = 200;
629         struct kmem_cache *cache;
630
631         cache = kmem_cache_create("test_cache", size, 0, 0, NULL);
632         if (!cache) {
633                 pr_err("Cache allocation failed\n");
634                 return;
635         }
636         pr_info("double-free on heap object\n");
637         p = kmem_cache_alloc(cache, GFP_KERNEL);
638         if (!p) {
639                 pr_err("Allocation failed\n");
640                 kmem_cache_destroy(cache);
641                 return;
642         }
643
644         kmem_cache_free(cache, p);
645         kmem_cache_free(cache, p);
646         kmem_cache_destroy(cache);
647 }
648
649 static noinline void __init kmem_cache_invalid_free(void)
650 {
651         char *p;
652         size_t size = 200;
653         struct kmem_cache *cache;
654
655         cache = kmem_cache_create("test_cache", size, 0, SLAB_TYPESAFE_BY_RCU,
656                                   NULL);
657         if (!cache) {
658                 pr_err("Cache allocation failed\n");
659                 return;
660         }
661         pr_info("invalid-free of heap object\n");
662         p = kmem_cache_alloc(cache, GFP_KERNEL);
663         if (!p) {
664                 pr_err("Allocation failed\n");
665                 kmem_cache_destroy(cache);
666                 return;
667         }
668
669         /* Trigger invalid free, the object doesn't get freed */
670         kmem_cache_free(cache, p + 1);
671
672         /*
673          * Properly free the object to prevent the "Objects remaining in
674          * test_cache on __kmem_cache_shutdown" BUG failure.
675          */
676         kmem_cache_free(cache, p);
677
678         kmem_cache_destroy(cache);
679 }
680
681 static noinline void __init kasan_memchr(void)
682 {
683         char *ptr;
684         size_t size = 24;
685
686         pr_info("out-of-bounds in memchr\n");
687         ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
688         if (!ptr)
689                 return;
690
691         kasan_ptr_result = memchr(ptr, '1', size + 1);
692         kfree(ptr);
693 }
694
695 static noinline void __init kasan_memcmp(void)
696 {
697         char *ptr;
698         size_t size = 24;
699         int arr[9];
700
701         pr_info("out-of-bounds in memcmp\n");
702         ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
703         if (!ptr)
704                 return;
705
706         memset(arr, 0, sizeof(arr));
707         kasan_int_result = memcmp(ptr, arr, size + 1);
708         kfree(ptr);
709 }
710
711 static noinline void __init kasan_strings(void)
712 {
713         char *ptr;
714         size_t size = 24;
715
716         pr_info("use-after-free in strchr\n");
717         ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
718         if (!ptr)
719                 return;
720
721         kfree(ptr);
722
723         /*
724          * Try to cause only 1 invalid access (less spam in dmesg).
725          * For that we need ptr to point to zeroed byte.
726          * Skip metadata that could be stored in freed object so ptr
727          * will likely point to zeroed byte.
728          */
729         ptr += 16;
730         kasan_ptr_result = strchr(ptr, '1');
731
732         pr_info("use-after-free in strrchr\n");
733         kasan_ptr_result = strrchr(ptr, '1');
734
735         pr_info("use-after-free in strcmp\n");
736         kasan_int_result = strcmp(ptr, "2");
737
738         pr_info("use-after-free in strncmp\n");
739         kasan_int_result = strncmp(ptr, "2", 1);
740
741         pr_info("use-after-free in strlen\n");
742         kasan_int_result = strlen(ptr);
743
744         pr_info("use-after-free in strnlen\n");
745         kasan_int_result = strnlen(ptr, 1);
746 }
747
748 static noinline void __init kasan_bitops(void)
749 {
750         /*
751          * Allocate 1 more byte, which causes kzalloc to round up to 16-bytes;
752          * this way we do not actually corrupt other memory.
753          */
754         long *bits = kzalloc(sizeof(*bits) + 1, GFP_KERNEL);
755         if (!bits)
756                 return;
757
758         /*
759          * Below calls try to access bit within allocated memory; however, the
760          * below accesses are still out-of-bounds, since bitops are defined to
761          * operate on the whole long the bit is in.
762          */
763         pr_info("out-of-bounds in set_bit\n");
764         set_bit(BITS_PER_LONG, bits);
765
766         pr_info("out-of-bounds in __set_bit\n");
767         __set_bit(BITS_PER_LONG, bits);
768
769         pr_info("out-of-bounds in clear_bit\n");
770         clear_bit(BITS_PER_LONG, bits);
771
772         pr_info("out-of-bounds in __clear_bit\n");
773         __clear_bit(BITS_PER_LONG, bits);
774
775         pr_info("out-of-bounds in clear_bit_unlock\n");
776         clear_bit_unlock(BITS_PER_LONG, bits);
777
778         pr_info("out-of-bounds in __clear_bit_unlock\n");
779         __clear_bit_unlock(BITS_PER_LONG, bits);
780
781         pr_info("out-of-bounds in change_bit\n");
782         change_bit(BITS_PER_LONG, bits);
783
784         pr_info("out-of-bounds in __change_bit\n");
785         __change_bit(BITS_PER_LONG, bits);
786
787         /*
788          * Below calls try to access bit beyond allocated memory.
789          */
790         pr_info("out-of-bounds in test_and_set_bit\n");
791         test_and_set_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
792
793         pr_info("out-of-bounds in __test_and_set_bit\n");
794         __test_and_set_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
795
796         pr_info("out-of-bounds in test_and_set_bit_lock\n");
797         test_and_set_bit_lock(BITS_PER_LONG + BITS_PER_BYTE, bits);
798
799         pr_info("out-of-bounds in test_and_clear_bit\n");
800         test_and_clear_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
801
802         pr_info("out-of-bounds in __test_and_clear_bit\n");
803         __test_and_clear_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
804
805         pr_info("out-of-bounds in test_and_change_bit\n");
806         test_and_change_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
807
808         pr_info("out-of-bounds in __test_and_change_bit\n");
809         __test_and_change_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
810
811         pr_info("out-of-bounds in test_bit\n");
812         kasan_int_result = test_bit(BITS_PER_LONG + BITS_PER_BYTE, bits);
813
814 #if defined(clear_bit_unlock_is_negative_byte)
815         pr_info("out-of-bounds in clear_bit_unlock_is_negative_byte\n");
816         kasan_int_result = clear_bit_unlock_is_negative_byte(BITS_PER_LONG +
817                 BITS_PER_BYTE, bits);
818 #endif
819         kfree(bits);
820 }
821
822 static noinline void __init kmalloc_double_kzfree(void)
823 {
824         char *ptr;
825         size_t size = 16;
826
827         pr_info("double-free (kfree_sensitive)\n");
828         ptr = kmalloc(size, GFP_KERNEL);
829         if (!ptr) {
830                 pr_err("Allocation failed\n");
831                 return;
832         }
833
834         kfree_sensitive(ptr);
835         kfree_sensitive(ptr);
836 }
837
838 #ifdef CONFIG_KASAN_VMALLOC
839 static noinline void __init vmalloc_oob(void)
840 {
841         void *area;
842
843         pr_info("vmalloc out-of-bounds\n");
844
845         /*
846          * We have to be careful not to hit the guard page.
847          * The MMU will catch that and crash us.
848          */
849         area = vmalloc(3000);
850         if (!area) {
851                 pr_err("Allocation failed\n");
852                 return;
853         }
854
855         ((volatile char *)area)[3100];
856         vfree(area);
857 }
858 #else
859 static void __init vmalloc_oob(void) {}
860 #endif
861
862 static struct kasan_rcu_info {
863         int i;
864         struct rcu_head rcu;
865 } *global_rcu_ptr;
866
867 static noinline void __init kasan_rcu_reclaim(struct rcu_head *rp)
868 {
869         struct kasan_rcu_info *fp = container_of(rp,
870                                                 struct kasan_rcu_info, rcu);
871
872         kfree(fp);
873         fp->i = 1;
874 }
875
876 static noinline void __init kasan_rcu_uaf(void)
877 {
878         struct kasan_rcu_info *ptr;
879
880         pr_info("use-after-free in kasan_rcu_reclaim\n");
881         ptr = kmalloc(sizeof(struct kasan_rcu_info), GFP_KERNEL);
882         if (!ptr) {
883                 pr_err("Allocation failed\n");
884                 return;
885         }
886
887         global_rcu_ptr = rcu_dereference_protected(ptr, NULL);
888         call_rcu(&global_rcu_ptr->rcu, kasan_rcu_reclaim);
889 }
890
891 static int __init kmalloc_tests_init(void)
892 {
893         /*
894          * Temporarily enable multi-shot mode. Otherwise, we'd only get a
895          * report for the first case.
896          */
897         bool multishot = kasan_save_enable_multi_shot();
898
899         kmalloc_oob_right();
900         kmalloc_oob_left();
901         kmalloc_node_oob_right();
902 #ifdef CONFIG_SLUB
903         kmalloc_pagealloc_oob_right();
904         kmalloc_pagealloc_uaf();
905         kmalloc_pagealloc_invalid_free();
906 #endif
907         kmalloc_large_oob_right();
908         kmalloc_oob_krealloc_more();
909         kmalloc_oob_krealloc_less();
910         kmalloc_oob_16();
911         kmalloc_oob_in_memset();
912         kmalloc_oob_memset_2();
913         kmalloc_oob_memset_4();
914         kmalloc_oob_memset_8();
915         kmalloc_oob_memset_16();
916         kmalloc_memmove_invalid_size();
917         kmalloc_uaf();
918         kmalloc_uaf_memset();
919         kmalloc_uaf2();
920         kfree_via_page();
921         kfree_via_phys();
922         kmem_cache_oob();
923         memcg_accounted_kmem_cache();
924         kasan_stack_oob();
925         kasan_global_oob();
926         kasan_alloca_oob_left();
927         kasan_alloca_oob_right();
928         ksize_unpoisons_memory();
929         copy_user_test();
930         kmem_cache_double_free();
931         kmem_cache_invalid_free();
932         kasan_memchr();
933         kasan_memcmp();
934         kasan_strings();
935         kasan_bitops();
936         kmalloc_double_kzfree();
937         vmalloc_oob();
938         kasan_rcu_uaf();
939
940         kasan_restore_multi_shot(multishot);
941
942         return -EAGAIN;
943 }
944
945 module_init(kmalloc_tests_init);
946 MODULE_LICENSE("GPL");