hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/misc/lkdtm/usercopy.c
....@@ -18,7 +18,7 @@
1818 * hardened usercopy checks by added "unconst" to all the const copies,
1919 * and making sure "cache_size" isn't optimized into a const.
2020 */
21
-static volatile size_t unconst = 0;
21
+static volatile size_t unconst;
2222 static volatile size_t cache_size = 1024;
2323 static struct kmem_cache *whitelist_cache;
2424
....@@ -30,12 +30,12 @@
3030 */
3131 static noinline unsigned char *trick_compiler(unsigned char *stack)
3232 {
33
- return stack + 0;
33
+ return stack + unconst;
3434 }
3535
3636 static noinline unsigned char *do_usercopy_stack_callee(int value)
3737 {
38
- unsigned char buf[32];
38
+ unsigned char buf[128];
3939 int i;
4040
4141 /* Exercise stack to avoid everything living in registers. */
....@@ -43,7 +43,12 @@
4343 buf[i] = value & 0xff;
4444 }
4545
46
- return trick_compiler(buf);
46
+ /*
47
+ * Put the target buffer in the middle of stack allocation
48
+ * so that we don't step on future stack users regardless
49
+ * of stack growth direction.
50
+ */
51
+ return trick_compiler(&buf[(128/2)-32]);
4752 }
4853
4954 static noinline void do_usercopy_stack(bool to_user, bool bad_frame)
....@@ -65,6 +70,12 @@
6570 bad_stack = task_stack_page(current) + THREAD_SIZE;
6671 bad_stack -= sizeof(unsigned long);
6772 }
73
+
74
+#ifdef ARCH_HAS_CURRENT_STACK_POINTER
75
+ pr_info("stack : %px\n", (void *)current_stack_pointer);
76
+#endif
77
+ pr_info("good_stack: %px-%px\n", good_stack, good_stack + sizeof(good_stack));
78
+ pr_info("bad_stack : %px-%px\n", bad_stack, bad_stack + sizeof(good_stack));
6879
6980 user_addr = vm_mmap(NULL, 0, PAGE_SIZE,
7081 PROT_READ | PROT_WRITE | PROT_EXEC,
....@@ -304,19 +315,22 @@
304315 return;
305316 }
306317
307
- pr_info("attempting good copy_to_user from kernel rodata\n");
318
+ pr_info("attempting good copy_to_user from kernel rodata: %px\n",
319
+ test_text);
308320 if (copy_to_user((void __user *)user_addr, test_text,
309321 unconst + sizeof(test_text))) {
310322 pr_warn("copy_to_user failed unexpectedly?!\n");
311323 goto free_user;
312324 }
313325
314
- pr_info("attempting bad copy_to_user from kernel text\n");
315
- if (copy_to_user((void __user *)user_addr, vm_mmap,
326
+ pr_info("attempting bad copy_to_user from kernel text: %px\n",
327
+ vm_mmap);
328
+ if (copy_to_user((void __user *)user_addr, __va_function(vm_mmap),
316329 unconst + PAGE_SIZE)) {
317330 pr_warn("copy_to_user failed, but lacked Oops\n");
318331 goto free_user;
319332 }
333
+ pr_err("FAIL: survived bad copy_to_user()\n");
320334
321335 free_user:
322336 vm_munmap(user_addr, PAGE_SIZE);