Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1341128
| From | Kees Cook <keescook@chromium.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | Re: [PATCH 2/2] lkdtm: Add read/write after free tests for buddy memory |
| Date | 2016-02-23 23:20 +0100 |
| Message-ID | <r5ttf-3q9-9@gated-at.bofh.it> (permalink) |
| References | <r59XA-6rQ-19@gated-at.bofh.it> <r59XB-6rQ-41@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
On Mon, Feb 22, 2016 at 5:27 PM, Laura Abbott <labbott@fedoraproject.org> wrote:
>
> The current tests for read/write after free work on slab
> allocated memory. Memory straight from the buddy allocator
> may behave slightly differently and have a different set
> of parameters to test. Add tests for those cases as well.
>
> On a basic x86 boot:
>
> # echo WRITE_BUDDY_AFTER_FREE > /sys/kernel/debug/provoke-crash/DIRECT
> [ 20.358964] lkdtm: Performing direct entry WRITE_BUDDY_AFTER_FREE
> [ 20.359979] lkdtm: Writing to the buddy page before free
> [ 20.360943] lkdtm: Writing to the buddy page after free
> [ 20.361838] lkdtm: Wrote to free page successfully
>
> # echo READ_BUDDY_AFTER_FREE > /sys/kernel/debug/provoke-crash/DIRECT
> [ 32.590826] lkdtm: Performing direct entry READ_BUDDY_AFTER_FREE
> [ 32.591692] lkdtm: Value in memory before free: 12345678
> [ 32.592459] lkdtm: Attempting to read from freed memory
> [ 32.593213] lkdtm: Successfully read value: 12345678
>
> On x86 with CONFIG_DEBUG_PAGEALLOC and debug_pagealloc=on:
>
> # echo WRITE_BUDDY_AFTER_FREE > /sys/kernel/debug/provoke-crash/DIRECT
> [ 49.761358] lkdtm: Performing direct entry WRITE_BUDDY_AFTER_FREE
> [ 49.762177] lkdtm: Writing to the buddy page before free
> [ 49.762890] lkdtm: Writing to the buddy page after free
> [ 49.763606] BUG: unable to handle kernel paging request at
> ffff880000034000
>
> # echo READ_BUDDY_AFTER_FREE > /sys/kernel/debug/provoke-crash/DIRECT
> [ 20.454176] lkdtm: Performing direct entry READ_BUDDY_AFTER_FREE
> [ 20.455198] lkdtm: Value in memory before free: 12345678
> [ 20.456107] BUG: unable to handle kernel paging request at
> ffff880000039000
>
> Note that arches without ARCH_SUPPORTS_DEBUG_PAGEALLOC may not
> produce the same crash.
As part of my benchmarking of all these changes, I'm going to end up
with matrix of what results can be expected under various states.
>
> Signed-off-by: Laura Abbott <labbott@fedoraproject.org>
> ---
> The examples I gave were for ARCH_SUPPORTS_DEBUG_PAGEALLOC because
> that's going to look different that the slab allocators. With
> page poisoning, the behavior is going to look similar to the slab
> allocators (write will succeed quietly, read should abort).
> ---
> drivers/misc/lkdtm.c | 40 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 40 insertions(+)
>
> diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
> index f95a582..2ef99e9 100644
> --- a/drivers/misc/lkdtm.c
> +++ b/drivers/misc/lkdtm.c
> @@ -93,6 +93,8 @@ enum ctype {
> CT_OVERWRITE_ALLOCATION,
> CT_WRITE_AFTER_FREE,
> CT_READ_AFTER_FREE,
> + CT_WRITE_BUDDY_AFTER_FREE,
> + CT_READ_BUDDY_AFTER_FREE,
> CT_SOFTLOCKUP,
> CT_HARDLOCKUP,
> CT_SPINLOCKUP,
> @@ -131,6 +133,8 @@ static char* cp_type[] = {
> "OVERWRITE_ALLOCATION",
> "WRITE_AFTER_FREE",
> "READ_AFTER_FREE",
> + "WRITE_BUDDY_AFTER_FREE",
> + "READ_BUDDY_AFTER_FREE",
> "SOFTLOCKUP",
> "HARDLOCKUP",
> "SPINLOCKUP",
> @@ -451,6 +455,42 @@ static void lkdtm_do_action(enum ctype which)
> kfree(val);
> break;
> }
> + case CT_WRITE_BUDDY_AFTER_FREE: {
> + unsigned long p = __get_free_page(GFP_KERNEL);
> + if (!p)
> + break;
> + pr_info("Writing to the buddy page before free\n");
> + memset((void *)p, 0x3, PAGE_SIZE);
> + free_page(p);
> + schedule();
> + pr_info("Writing to the buddy page after free\n");
I think it might be clearer to have these read like this:
Attempting good write to buddy page before free
Attempting bad write to buddy page after free
Unexpectedly wrote to free page!
> + memset((void *)p, 0x78, PAGE_SIZE);
> + pr_info("Wrote to free page successfully\n");
> + break;
> + }
> + case CT_READ_BUDDY_AFTER_FREE: {
> + unsigned long p = __get_free_page(GFP_KERNEL);
> + int *tmp, *val = kmalloc(1024, GFP_KERNEL);
> + int **base;
> +
> + if (!p)
> + break;
> +
> + if (!val)
> + break;
> +
> + base = (int **)p;
> +
> + *val = 0x12345678;
> + pr_info("Value in memory before free: %x\n", *val);
> + base[0] = val;
> + free_page(p);
> + tmp = base[0];
> + pr_info("Attempting to read from freed memory\n");
> + pr_info("Successfully read value: %x\n", *tmp);
Attempting bad read from freed memory
Unexpectedly read value: %x
> + kfree(val);
> + break;
> + }
> case CT_SOFTLOCKUP:
> preempt_disable();
> for (;;)
> --
> 2.5.0
>
But I think these changes could be done later -- best to try to make
all the test reports say similar things. (e.g. right now the EXEC_*
cases don't say "Oh no, I failed" if they failed to Oops.)
-Kees
--
Kees Cook
Chrome OS & Brillo Security
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 0/2] LKDTM test updates Laura Abbott <labbott@fedoraproject.org> - 2016-02-23 02:30 +0100
[PATCH 2/2] lkdtm: Add read/write after free tests for buddy memory Laura Abbott <labbott@fedoraproject.org> - 2016-02-23 02:30 +0100
Re: [PATCH 2/2] lkdtm: Add read/write after free tests for buddy memory Kees Cook <keescook@chromium.org> - 2016-02-23 23:20 +0100
[PATCHv3 1/2] lkdtm: Add READ_AFTER_FREE test Laura Abbott <labbott@fedoraproject.org> - 2016-02-23 02:30 +0100
csiph-web