]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - lib/test_kasan_module.c
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5 * Author: Andrey Ryabinin <a.ryabinin@samsung.com>
8 #define pr_fmt(fmt) "kasan test: %s " fmt, __func__
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>
16 #include "../mm/kasan/kasan.h"
18 static noinline
void __init
copy_user_test(void)
22 size_t size
= 128 - KASAN_GRANULE_SIZE
;
23 int __maybe_unused unused
;
25 kmem
= kmalloc(size
, GFP_KERNEL
);
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(usermem
)) {
33 pr_err("Failed to allocate user memory\n");
38 pr_info("out-of-bounds in copy_from_user()\n");
39 unused
= copy_from_user(kmem
, usermem
, size
+ 1);
41 pr_info("out-of-bounds in copy_to_user()\n");
42 unused
= copy_to_user(usermem
, kmem
, size
+ 1);
44 pr_info("out-of-bounds in __copy_from_user()\n");
45 unused
= __copy_from_user(kmem
, usermem
, size
+ 1);
47 pr_info("out-of-bounds in __copy_to_user()\n");
48 unused
= __copy_to_user(usermem
, kmem
, size
+ 1);
50 pr_info("out-of-bounds in __copy_from_user_inatomic()\n");
51 unused
= __copy_from_user_inatomic(kmem
, usermem
, size
+ 1);
53 pr_info("out-of-bounds in __copy_to_user_inatomic()\n");
54 unused
= __copy_to_user_inatomic(usermem
, kmem
, size
+ 1);
56 pr_info("out-of-bounds in strncpy_from_user()\n");
57 unused
= strncpy_from_user(kmem
, usermem
, size
+ 1);
59 vm_munmap((unsigned long)usermem
, PAGE_SIZE
);
63 static struct kasan_rcu_info
{
68 static noinline
void __init
kasan_rcu_reclaim(struct rcu_head
*rp
)
70 struct kasan_rcu_info
*fp
= container_of(rp
,
71 struct kasan_rcu_info
, rcu
);
74 ((volatile struct kasan_rcu_info
*)fp
)->i
;
77 static noinline
void __init
kasan_rcu_uaf(void)
79 struct kasan_rcu_info
*ptr
;
81 pr_info("use-after-free in kasan_rcu_reclaim\n");
82 ptr
= kmalloc(sizeof(struct kasan_rcu_info
), GFP_KERNEL
);
84 pr_err("Allocation failed\n");
88 global_rcu_ptr
= rcu_dereference_protected(ptr
, NULL
);
89 call_rcu(&global_rcu_ptr
->rcu
, kasan_rcu_reclaim
);
92 static noinline
void __init
kasan_workqueue_work(struct work_struct
*work
)
97 static noinline
void __init
kasan_workqueue_uaf(void)
99 struct workqueue_struct
*workqueue
;
100 struct work_struct
*work
;
102 workqueue
= create_workqueue("kasan_wq_test");
104 pr_err("Allocation failed\n");
107 work
= kmalloc(sizeof(struct work_struct
), GFP_KERNEL
);
109 pr_err("Allocation failed\n");
113 INIT_WORK(work
, kasan_workqueue_work
);
114 queue_work(workqueue
, work
);
115 destroy_workqueue(workqueue
);
117 pr_info("use-after-free on workqueue\n");
118 ((volatile struct work_struct
*)work
)->data
;
121 static int __init
test_kasan_module_init(void)
124 * Temporarily enable multi-shot mode. Otherwise, KASAN would only
125 * report the first detected bug and panic the kernel if panic_on_warn
128 bool multishot
= kasan_save_enable_multi_shot();
132 kasan_workqueue_uaf();
134 kasan_restore_multi_shot(multishot
);
138 module_init(test_kasan_module_init
);
139 MODULE_LICENSE("GPL");