Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lkdtm: add "WRITE_KERN" test

Add "WRITE_KERN" crash target to validate that kernel executable memory
is not writable.

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Kees Cook and committed by
Greg Kroah-Hartman
dc2b9e90 aac416fc

+25
+25
drivers/misc/lkdtm.c
··· 102 102 CT_EXEC_USERSPACE, 103 103 CT_ACCESS_USERSPACE, 104 104 CT_WRITE_RO, 105 + CT_WRITE_KERN, 105 106 }; 106 107 107 108 static char* cp_name[] = { ··· 139 138 "EXEC_USERSPACE", 140 139 "ACCESS_USERSPACE", 141 140 "WRITE_RO", 141 + "WRITE_KERN", 142 142 }; 143 143 144 144 static struct jprobe lkdtm; ··· 316 314 317 315 static void do_nothing(void) 318 316 { 317 + return; 318 + } 319 + 320 + /* Must immediately follow do_nothing for size calculuations to work out. */ 321 + static void do_overwritten(void) 322 + { 323 + pr_info("do_overwritten wasn't overwritten!\n"); 319 324 return; 320 325 } 321 326 ··· 503 494 pr_info("attempting bad write at %p\n", ptr); 504 495 *ptr ^= 0xabcd1234; 505 496 497 + break; 498 + } 499 + case CT_WRITE_KERN: { 500 + size_t size; 501 + unsigned char *ptr; 502 + 503 + size = (unsigned long)do_overwritten - 504 + (unsigned long)do_nothing; 505 + ptr = (unsigned char *)do_overwritten; 506 + 507 + pr_info("attempting bad %zu byte write at %p\n", size, ptr); 508 + memcpy(ptr, (unsigned char *)do_nothing, size); 509 + flush_icache_range((unsigned long)ptr, 510 + (unsigned long)(ptr + size)); 511 + 512 + do_overwritten(); 506 513 break; 507 514 } 508 515 case CT_NONE: