1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * This is for all the tests related to logic bugs (e.g. bad dereferences, 4 * bad alignment, bad loops, bad locking, bad scheduling, deep stacks, and 5 * lockups) along with other things that don't fit well into existing LKDTM 6 * test source files. 7 */ 8 #include "lkdtm.h" 9 #include <linux/list.h> 10 #include <linux/sched.h> 11 #include <linux/sched/signal.h> 12 #include <linux/sched/task_stack.h> 13 #include <linux/uaccess.h> 14 #include <linux/slab.h> 15 16 #ifdef CONFIG_X86_32 17 #include <asm/desc.h> 18 #endif 19 20 struct lkdtm_list { 21 struct list_head node; 22 }; 23 24 /* 25 * Make sure our attempts to over run the kernel stack doesn't trigger 26 * a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we 27 * recurse past the end of THREAD_SIZE by default. 28 */ 29 #if defined(CONFIG_FRAME_WARN) && (CONFIG_FRAME_WARN > 0) 30 #define REC_STACK_SIZE (_AC(CONFIG_FRAME_WARN, UL) / 2) 31 #else 32 #define REC_STACK_SIZE (THREAD_SIZE / 8) 33 #endif 34 #define REC_NUM_DEFAULT ((THREAD_SIZE / REC_STACK_SIZE) * 2) 35 36 static int recur_count = REC_NUM_DEFAULT; 37 38 static DEFINE_SPINLOCK(lock_me_up); 39 40 /* 41 * Make sure compiler does not optimize this function or stack frame away: 42 * - function marked noinline 43 * - stack variables are marked volatile 44 * - stack variables are written (memset()) and read (pr_info()) 45 * - function has external effects (pr_info()) 46 * */ 47 static int noinline recursive_loop(int remaining) 48 { 49 volatile char buf[REC_STACK_SIZE]; 50 51 memset((void *)buf, remaining & 0xFF, sizeof(buf)); 52 pr_info("loop %d/%d ...\n", (int)buf[remaining % sizeof(buf)], 53 recur_count); 54 if (!remaining) 55 return 0; 56 else 57 return recursive_loop(remaining - 1); 58 } 59 60 /* If the depth is negative, use the default, otherwise keep parameter. */ 61 void __init lkdtm_bugs_init(int *recur_param) 62 { 63 if (*recur_param < 0) 64 *recur_param = recur_count; 65 else 66 recur_count = *recur_param; 67 } 68 69 void lkdtm_PANIC(void) 70 { 71 panic("dumptest"); 72 } 73 74 void lkdtm_BUG(void) 75 { 76 BUG(); 77 } 78 79 static int warn_counter; 80 81 void lkdtm_WARNING(void) 82 { 83 WARN_ON(++warn_counter); 84 } 85 86 void lkdtm_WARNING_MESSAGE(void) 87 { 88 WARN(1, "Warning message trigger count: %d\n", ++warn_counter); 89 } 90 91 void lkdtm_EXCEPTION(void) 92 { 93 *((volatile int *) 0) = 0; 94 } 95 96 void lkdtm_LOOP(void) 97 { 98 for (;;) 99 ; 100 } 101 102 void lkdtm_EXHAUST_STACK(void) 103 { 104 pr_info("Calling function with %lu frame size to depth %d ...\n", 105 REC_STACK_SIZE, recur_count); 106 recursive_loop(recur_count); 107 pr_info("FAIL: survived without exhausting stack?!\n"); 108 } 109 110 static noinline void __lkdtm_CORRUPT_STACK(void *stack) 111 { 112 memset(stack, '\xff', 64); 113 } 114 115 /* This should trip the stack canary, not corrupt the return address. */ 116 noinline void lkdtm_CORRUPT_STACK(void) 117 { 118 /* Use default char array length that triggers stack protection. */ 119 char data[8] __aligned(sizeof(void *)); 120 121 __lkdtm_CORRUPT_STACK(&data); 122 123 pr_info("Corrupted stack containing char array ...\n"); 124 } 125 126 /* Same as above but will only get a canary with -fstack-protector-strong */ 127 noinline void lkdtm_CORRUPT_STACK_STRONG(void) 128 { 129 union { 130 unsigned short shorts[4]; 131 unsigned long *ptr; 132 } data __aligned(sizeof(void *)); 133 134 __lkdtm_CORRUPT_STACK(&data); 135 136 pr_info("Corrupted stack containing union ...\n"); 137 } 138 139 void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void) 140 { 141 static u8 data[5] __attribute__((aligned(4))) = {1, 2, 3, 4, 5}; 142 u32 *p; 143 u32 val = 0x12345678; 144 145 p = (u32 *)(data + 1); 146 if (*p == 0) 147 val = 0x87654321; 148 *p = val; 149 } 150 151 void lkdtm_SOFTLOCKUP(void) 152 { 153 preempt_disable(); 154 for (;;) 155 cpu_relax(); 156 } 157 158 void lkdtm_HARDLOCKUP(void) 159 { 160 local_irq_disable(); 161 for (;;) 162 cpu_relax(); 163 } 164 165 void lkdtm_SPINLOCKUP(void) 166 { 167 /* Must be called twice to trigger. */ 168 spin_lock(&lock_me_up); 169 /* Let sparse know we intended to exit holding the lock. */ 170 __release(&lock_me_up); 171 } 172 173 void lkdtm_HUNG_TASK(void) 174 { 175 set_current_state(TASK_UNINTERRUPTIBLE); 176 schedule(); 177 } 178 179 volatile unsigned int huge = INT_MAX - 2; 180 volatile unsigned int ignored; 181 182 void lkdtm_OVERFLOW_SIGNED(void) 183 { 184 int value; 185 186 value = huge; 187 pr_info("Normal signed addition ...\n"); 188 value += 1; 189 ignored = value; 190 191 pr_info("Overflowing signed addition ...\n"); 192 value += 4; 193 ignored = value; 194 } 195 196 197 void lkdtm_OVERFLOW_UNSIGNED(void) 198 { 199 unsigned int value; 200 201 value = huge; 202 pr_info("Normal unsigned addition ...\n"); 203 value += 1; 204 ignored = value; 205 206 pr_info("Overflowing unsigned addition ...\n"); 207 value += 4; 208 ignored = value; 209 } 210 211 /* Intentially using old-style flex array definition of 1 byte. */ 212 struct array_bounds_flex_array { 213 int one; 214 int two; 215 char data[1]; 216 }; 217 218 struct array_bounds { 219 int one; 220 int two; 221 char data[8]; 222 int three; 223 }; 224 225 void lkdtm_ARRAY_BOUNDS(void) 226 { 227 struct array_bounds_flex_array *not_checked; 228 struct array_bounds *checked; 229 volatile int i; 230 231 not_checked = kmalloc(sizeof(*not_checked) * 2, GFP_KERNEL); 232 checked = kmalloc(sizeof(*checked) * 2, GFP_KERNEL); 233 234 pr_info("Array access within bounds ...\n"); 235 /* For both, touch all bytes in the actual member size. */ 236 for (i = 0; i < sizeof(checked->data); i++) 237 checked->data[i] = 'A'; 238 /* 239 * For the uninstrumented flex array member, also touch 1 byte 240 * beyond to verify it is correctly uninstrumented. 241 */ 242 for (i = 0; i < sizeof(not_checked->data) + 1; i++) 243 not_checked->data[i] = 'A'; 244 245 pr_info("Array access beyond bounds ...\n"); 246 for (i = 0; i < sizeof(checked->data) + 1; i++) 247 checked->data[i] = 'B'; 248 249 kfree(not_checked); 250 kfree(checked); 251 } 252 253 void lkdtm_CORRUPT_LIST_ADD(void) 254 { 255 /* 256 * Initially, an empty list via LIST_HEAD: 257 * test_head.next = &test_head 258 * test_head.prev = &test_head 259 */ 260 LIST_HEAD(test_head); 261 struct lkdtm_list good, bad; 262 void *target[2] = { }; 263 void *redirection = ⌖ 264 265 pr_info("attempting good list addition\n"); 266 267 /* 268 * Adding to the list performs these actions: 269 * test_head.next->prev = &good.node 270 * good.node.next = test_head.next 271 * good.node.prev = test_head 272 * test_head.next = good.node 273 */ 274 list_add(&good.node, &test_head); 275 276 pr_info("attempting corrupted list addition\n"); 277 /* 278 * In simulating this "write what where" primitive, the "what" is 279 * the address of &bad.node, and the "where" is the address held 280 * by "redirection". 281 */ 282 test_head.next = redirection; 283 list_add(&bad.node, &test_head); 284 285 if (target[0] == NULL && target[1] == NULL) 286 pr_err("Overwrite did not happen, but no BUG?!\n"); 287 else 288 pr_err("list_add() corruption not detected!\n"); 289 } 290 291 void lkdtm_CORRUPT_LIST_DEL(void) 292 { 293 LIST_HEAD(test_head); 294 struct lkdtm_list item; 295 void *target[2] = { }; 296 void *redirection = ⌖ 297 298 list_add(&item.node, &test_head); 299 300 pr_info("attempting good list removal\n"); 301 list_del(&item.node); 302 303 pr_info("attempting corrupted list removal\n"); 304 list_add(&item.node, &test_head); 305 306 /* As with the list_add() test above, this corrupts "next". */ 307 item.node.next = redirection; 308 list_del(&item.node); 309 310 if (target[0] == NULL && target[1] == NULL) 311 pr_err("Overwrite did not happen, but no BUG?!\n"); 312 else 313 pr_err("list_del() corruption not detected!\n"); 314 } 315 316 /* Test if unbalanced set_fs(KERNEL_DS)/set_fs(USER_DS) check exists. */ 317 void lkdtm_CORRUPT_USER_DS(void) 318 { 319 pr_info("setting bad task size limit\n"); 320 set_fs(KERNEL_DS); 321 322 /* Make sure we do not keep running with a KERNEL_DS! */ 323 force_sig(SIGKILL); 324 } 325 326 /* Test that VMAP_STACK is actually allocating with a leading guard page */ 327 void lkdtm_STACK_GUARD_PAGE_LEADING(void) 328 { 329 const unsigned char *stack = task_stack_page(current); 330 const unsigned char *ptr = stack - 1; 331 volatile unsigned char byte; 332 333 pr_info("attempting bad read from page below current stack\n"); 334 335 byte = *ptr; 336 337 pr_err("FAIL: accessed page before stack!\n"); 338 } 339 340 /* Test that VMAP_STACK is actually allocating with a trailing guard page */ 341 void lkdtm_STACK_GUARD_PAGE_TRAILING(void) 342 { 343 const unsigned char *stack = task_stack_page(current); 344 const unsigned char *ptr = stack + THREAD_SIZE; 345 volatile unsigned char byte; 346 347 pr_info("attempting bad read from page above current stack\n"); 348 349 byte = *ptr; 350 351 pr_err("FAIL: accessed page after stack!\n"); 352 } 353 354 void lkdtm_UNSET_SMEP(void) 355 { 356 #if IS_ENABLED(CONFIG_X86_64) && !IS_ENABLED(CONFIG_UML) 357 #define MOV_CR4_DEPTH 64 358 void (*direct_write_cr4)(unsigned long val); 359 unsigned char *insn; 360 unsigned long cr4; 361 int i; 362 363 cr4 = native_read_cr4(); 364 365 if ((cr4 & X86_CR4_SMEP) != X86_CR4_SMEP) { 366 pr_err("FAIL: SMEP not in use\n"); 367 return; 368 } 369 cr4 &= ~(X86_CR4_SMEP); 370 371 pr_info("trying to clear SMEP normally\n"); 372 native_write_cr4(cr4); 373 if (cr4 == native_read_cr4()) { 374 pr_err("FAIL: pinning SMEP failed!\n"); 375 cr4 |= X86_CR4_SMEP; 376 pr_info("restoring SMEP\n"); 377 native_write_cr4(cr4); 378 return; 379 } 380 pr_info("ok: SMEP did not get cleared\n"); 381 382 /* 383 * To test the post-write pinning verification we need to call 384 * directly into the middle of native_write_cr4() where the 385 * cr4 write happens, skipping any pinning. This searches for 386 * the cr4 writing instruction. 387 */ 388 insn = (unsigned char *)native_write_cr4; 389 for (i = 0; i < MOV_CR4_DEPTH; i++) { 390 /* mov %rdi, %cr4 */ 391 if (insn[i] == 0x0f && insn[i+1] == 0x22 && insn[i+2] == 0xe7) 392 break; 393 /* mov %rdi,%rax; mov %rax, %cr4 */ 394 if (insn[i] == 0x48 && insn[i+1] == 0x89 && 395 insn[i+2] == 0xf8 && insn[i+3] == 0x0f && 396 insn[i+4] == 0x22 && insn[i+5] == 0xe0) 397 break; 398 } 399 if (i >= MOV_CR4_DEPTH) { 400 pr_info("ok: cannot locate cr4 writing call gadget\n"); 401 return; 402 } 403 direct_write_cr4 = (void *)(insn + i); 404 405 pr_info("trying to clear SMEP with call gadget\n"); 406 direct_write_cr4(cr4); 407 if (native_read_cr4() & X86_CR4_SMEP) { 408 pr_info("ok: SMEP removal was reverted\n"); 409 } else { 410 pr_err("FAIL: cleared SMEP not detected!\n"); 411 cr4 |= X86_CR4_SMEP; 412 pr_info("restoring SMEP\n"); 413 native_write_cr4(cr4); 414 } 415 #else 416 pr_err("XFAIL: this test is x86_64-only\n"); 417 #endif 418 } 419 420 void lkdtm_DOUBLE_FAULT(void) 421 { 422 #ifdef CONFIG_X86_32 423 /* 424 * Trigger #DF by setting the stack limit to zero. This clobbers 425 * a GDT TLS slot, which is okay because the current task will die 426 * anyway due to the double fault. 427 */ 428 struct desc_struct d = { 429 .type = 3, /* expand-up, writable, accessed data */ 430 .p = 1, /* present */ 431 .d = 1, /* 32-bit */ 432 .g = 0, /* limit in bytes */ 433 .s = 1, /* not system */ 434 }; 435 436 local_irq_disable(); 437 write_gdt_entry(get_cpu_gdt_rw(smp_processor_id()), 438 GDT_ENTRY_TLS_MIN, &d, DESCTYPE_S); 439 440 /* 441 * Put our zero-limit segment in SS and then trigger a fault. The 442 * 4-byte access to (%esp) will fault with #SS, and the attempt to 443 * deliver the fault will recursively cause #SS and result in #DF. 444 * This whole process happens while NMIs and MCEs are blocked by the 445 * MOV SS window. This is nice because an NMI with an invalid SS 446 * would also double-fault, resulting in the NMI or MCE being lost. 447 */ 448 asm volatile ("movw %0, %%ss; addl $0, (%%esp)" :: 449 "r" ((unsigned short)(GDT_ENTRY_TLS_MIN << 3))); 450 451 pr_err("FAIL: tried to double fault but didn't die\n"); 452 #else 453 pr_err("XFAIL: this test is ia32-only\n"); 454 #endif 455 } 456 457 #ifdef CONFIG_ARM64_PTR_AUTH 458 static noinline void change_pac_parameters(void) 459 { 460 /* Reset the keys of current task */ 461 ptrauth_thread_init_kernel(current); 462 ptrauth_thread_switch_kernel(current); 463 } 464 465 #define CORRUPT_PAC_ITERATE 10 466 noinline void lkdtm_CORRUPT_PAC(void) 467 { 468 int i; 469 470 if (!system_supports_address_auth()) { 471 pr_err("FAIL: arm64 pointer authentication feature not present\n"); 472 return; 473 } 474 475 pr_info("Change the PAC parameters to force function return failure\n"); 476 /* 477 * Pac is a hash value computed from input keys, return address and 478 * stack pointer. As pac has fewer bits so there is a chance of 479 * collision, so iterate few times to reduce the collision probability. 480 */ 481 for (i = 0; i < CORRUPT_PAC_ITERATE; i++) 482 change_pac_parameters(); 483 484 pr_err("FAIL: %s test failed. Kernel may be unstable from here\n", __func__); 485 } 486 #else /* !CONFIG_ARM64_PTR_AUTH */ 487 noinline void lkdtm_CORRUPT_PAC(void) 488 { 489 pr_err("FAIL: arm64 pointer authentication config disabled\n"); 490 } 491 #endif 492