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