summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2016-02-26 18:27:35 -0500
committerKees Cook <keescook@chromium.org>2016-03-01 17:29:16 -0500
commit7c0ae5be821c1b6a700c5506de9b62e95f60df3c (patch)
tree8fc2ec6f89e2a2ceb36822397f47046ac22008c8
parent5fd9e48084f5566aafb759882f549f37e5940501 (diff)
lkdtm: improve use-after-free tests
This improves the order of operations on the use-after-free tests to try to make sure we've executed any available sanity-checking code, and to report the poisoning that was found. Signed-off-by: Kees Cook <keescook@chromium.org>
-rw-r--r--drivers/misc/lkdtm.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index c333e813ed34..9345999f5673 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -417,7 +417,7 @@ static void lkdtm_do_action(enum ctype which)
417 break; 417 break;
418 } 418 }
419 case CT_WRITE_AFTER_FREE: { 419 case CT_WRITE_AFTER_FREE: {
420 int *base; 420 int *base, *again;
421 size_t len = 1024; 421 size_t len = 1024;
422 /* 422 /*
423 * The slub allocator uses the first word to store the free 423 * The slub allocator uses the first word to store the free
@@ -428,10 +428,16 @@ static void lkdtm_do_action(enum ctype which)
428 428
429 base = kmalloc(len, GFP_KERNEL); 429 base = kmalloc(len, GFP_KERNEL);
430 pr_info("Allocated memory %p-%p\n", base, &base[offset * 2]); 430 pr_info("Allocated memory %p-%p\n", base, &base[offset * 2]);
431 kfree(base);
432 pr_info("Attempting bad write to freed memory at %p\n", 431 pr_info("Attempting bad write to freed memory at %p\n",
433 &base[offset]); 432 &base[offset]);
433 kfree(base);
434 base[offset] = 0x0abcdef0; 434 base[offset] = 0x0abcdef0;
435 /* Attempt to notice the overwrite. */
436 again = kmalloc(len, GFP_KERNEL);
437 kfree(again);
438 if (again != base)
439 pr_info("Hmm, didn't get the same memory range.\n");
440
435 break; 441 break;
436 } 442 }
437 case CT_READ_AFTER_FREE: { 443 case CT_READ_AFTER_FREE: {
@@ -462,7 +468,7 @@ static void lkdtm_do_action(enum ctype which)
462 saw = base[offset]; 468 saw = base[offset];
463 if (saw != *val) { 469 if (saw != *val) {
464 /* Good! Poisoning happened, so declare a win. */ 470 /* Good! Poisoning happened, so declare a win. */
465 pr_info("Memory correctly poisoned, calling BUG\n"); 471 pr_info("Memory correctly poisoned (%x)\n", saw);
466 BUG(); 472 BUG();
467 } 473 }
468 pr_info("Memory was not poisoned\n"); 474 pr_info("Memory was not poisoned\n");
@@ -480,6 +486,11 @@ static void lkdtm_do_action(enum ctype which)
480 schedule(); 486 schedule();
481 pr_info("Attempting bad write to the buddy page after free\n"); 487 pr_info("Attempting bad write to the buddy page after free\n");
482 memset((void *)p, 0x78, PAGE_SIZE); 488 memset((void *)p, 0x78, PAGE_SIZE);
489 /* Attempt to notice the overwrite. */
490 p = __get_free_page(GFP_KERNEL);
491 free_page(p);
492 schedule();
493
483 break; 494 break;
484 } 495 }
485 case CT_READ_BUDDY_AFTER_FREE: { 496 case CT_READ_BUDDY_AFTER_FREE: {
@@ -503,7 +514,7 @@ static void lkdtm_do_action(enum ctype which)
503 saw = base[0]; 514 saw = base[0];
504 if (saw != *val) { 515 if (saw != *val) {
505 /* Good! Poisoning happened, so declare a win. */ 516 /* Good! Poisoning happened, so declare a win. */
506 pr_info("Buddy page correctly poisoned, calling BUG\n"); 517 pr_info("Memory correctly poisoned (%x)\n", saw);
507 BUG(); 518 BUG();
508 } 519 }
509 pr_info("Buddy page was not poisoned\n"); 520 pr_info("Buddy page was not poisoned\n");