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: " fmt |
9 | |
10 | #include <linux/mman.h> |
11 | #include <linux/module.h> |
12 | #include <linux/printk.h> |
13 | #include <linux/slab.h> |
14 | #include <linux/uaccess.h> |
15 | |
16 | #include "kasan.h" |
17 | |
18 | static noinline void __init copy_user_test(void) |
19 | { |
20 | char *kmem; |
21 | char __user *usermem; |
22 | size_t size = 128 - KASAN_GRANULE_SIZE; |
23 | int __maybe_unused unused; |
24 | |
25 | kmem = kmalloc(size, GFP_KERNEL); |
26 | if (!kmem) |
27 | return; |
28 | |
29 | usermem = (char __user *)vm_mmap(NULL, 0, PAGE_SIZE, |
30 | PROT_READ | PROT_WRITE | PROT_EXEC, |
31 | MAP_ANONYMOUS | MAP_PRIVATE, 0); |
32 | if (IS_ERR(ptr: usermem)) { |
33 | pr_err("Failed to allocate user memory\n" ); |
34 | kfree(objp: kmem); |
35 | return; |
36 | } |
37 | |
38 | OPTIMIZER_HIDE_VAR(size); |
39 | |
40 | pr_info("out-of-bounds in copy_from_user()\n" ); |
41 | unused = copy_from_user(to: kmem, from: usermem, n: size + 1); |
42 | |
43 | pr_info("out-of-bounds in copy_to_user()\n" ); |
44 | unused = copy_to_user(to: usermem, from: kmem, n: size + 1); |
45 | |
46 | pr_info("out-of-bounds in __copy_from_user()\n" ); |
47 | unused = __copy_from_user(to: kmem, from: usermem, n: size + 1); |
48 | |
49 | pr_info("out-of-bounds in __copy_to_user()\n" ); |
50 | unused = __copy_to_user(to: usermem, from: kmem, n: size + 1); |
51 | |
52 | pr_info("out-of-bounds in __copy_from_user_inatomic()\n" ); |
53 | unused = __copy_from_user_inatomic(to: kmem, from: usermem, n: size + 1); |
54 | |
55 | pr_info("out-of-bounds in __copy_to_user_inatomic()\n" ); |
56 | unused = __copy_to_user_inatomic(to: usermem, from: kmem, n: size + 1); |
57 | |
58 | pr_info("out-of-bounds in strncpy_from_user()\n" ); |
59 | unused = strncpy_from_user(dst: kmem, src: usermem, count: size + 1); |
60 | |
61 | vm_munmap((unsigned long)usermem, PAGE_SIZE); |
62 | kfree(objp: kmem); |
63 | } |
64 | |
65 | static int __init kasan_test_module_init(void) |
66 | { |
67 | /* |
68 | * Temporarily enable multi-shot mode. Otherwise, KASAN would only |
69 | * report the first detected bug and panic the kernel if panic_on_warn |
70 | * is enabled. |
71 | */ |
72 | bool multishot = kasan_save_enable_multi_shot(); |
73 | |
74 | copy_user_test(); |
75 | |
76 | kasan_restore_multi_shot(multishot); |
77 | return -EAGAIN; |
78 | } |
79 | |
80 | module_init(kasan_test_module_init); |
81 | MODULE_LICENSE("GPL" ); |
82 | |