Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1579166 > unrolled thread

[PATCH] usercopy: add testcases to check zeroing on failure of usercopy

Started byHoeun Ryu <hoeun.ryu@gmail.com>
First post2017-02-12 07:20 +0100
Last post2017-02-13 19:40 +0100
Articles 3 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] usercopy: add testcases to check zeroing on failure of usercopy Hoeun Ryu <hoeun.ryu@gmail.com> - 2017-02-12 07:20 +0100
    Re: [PATCH] usercopy: add testcases to check zeroing on failure of usercopy Kees Cook <keescook@chromium.org> - 2017-02-13 19:30 +0100
    Re: [PATCH] usercopy: add testcases to check zeroing on failure of usercopy Kees Cook <keescook@chromium.org> - 2017-02-13 19:40 +0100

#1579166 — [PATCH] usercopy: add testcases to check zeroing on failure of usercopy

FromHoeun Ryu <hoeun.ryu@gmail.com>
Date2017-02-12 07:20 +0100
Subject[PATCH] usercopy: add testcases to check zeroing on failure of usercopy
Message-ID<t9VFT-2JK-1@gated-at.bofh.it>
In the hardend usercopy, the destination buffer will be zeroed if
copy_from_user/get_user fails. This patch adds testcases for it.
The destination buffer is set with non-zero value before illegal
copy_from_user/get_user is executed and the buffer is compared to
zero after usercopy is done.

Signed-off-by: Hoeun Ryu <hoeun.ryu@gmail.com>
---
 lib/test_user_copy.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/lib/test_user_copy.c b/lib/test_user_copy.c
index 0ecef3e..54bd898 100644
--- a/lib/test_user_copy.c
+++ b/lib/test_user_copy.c
@@ -41,11 +41,18 @@ static int __init test_user_copy_init(void)
 	char *bad_usermem;
 	unsigned long user_addr;
 	unsigned long value = 0x5A;
+	char *zerokmem;
 
 	kmem = kmalloc(PAGE_SIZE * 2, GFP_KERNEL);
 	if (!kmem)
 		return -ENOMEM;
 
+	zerokmem = kzalloc(PAGE_SIZE * 2, GFP_KERNEL);
+	if (!zerokmem) {
+		kfree(kmem);
+		return -ENOMEM;
+	}
+
 	user_addr = vm_mmap(NULL, 0, PAGE_SIZE * 2,
 			    PROT_READ | PROT_WRITE | PROT_EXEC,
 			    MAP_ANONYMOUS | MAP_PRIVATE, 0);
@@ -69,25 +76,35 @@ static int __init test_user_copy_init(void)
 		    "legitimate put_user failed");
 
 	/* Invalid usage: none of these should succeed. */
+	memset(kmem, 0x5A, PAGE_SIZE);
 	ret |= test(!copy_from_user(kmem, (char __user *)(kmem + PAGE_SIZE),
 				    PAGE_SIZE),
 		    "illegal all-kernel copy_from_user passed");
+	ret |= test(memcmp(zerokmem, kmem, PAGE_SIZE),
+		    "zeroing failure for illegal all-kernel copy_from_user");
+	memset(bad_usermem, 0x5A, PAGE_SIZE);
 	ret |= test(!copy_from_user(bad_usermem, (char __user *)kmem,
 				    PAGE_SIZE),
 		    "illegal reversed copy_from_user passed");
+	ret |= test(memcmp(zerokmem, bad_usermem, PAGE_SIZE),
+		    "zeroing failure for illegal reversed copy_from_user");
 	ret |= test(!copy_to_user((char __user *)kmem, kmem + PAGE_SIZE,
 				  PAGE_SIZE),
 		    "illegal all-kernel copy_to_user passed");
 	ret |= test(!copy_to_user((char __user *)kmem, bad_usermem,
 				  PAGE_SIZE),
 		    "illegal reversed copy_to_user passed");
+	memset(kmem, 0x5A, PAGE_SIZE);
 	ret |= test(!get_user(value, (unsigned long __user *)kmem),
 		    "illegal get_user passed");
+	ret |= test(memcmp(zerokmem, kmem, sizeof(value)),
+		    "zeroing failure for illegal get_user");
 	ret |= test(!put_user(value, (unsigned long __user *)kmem),
 		    "illegal put_user passed");
 
 	vm_munmap(user_addr, PAGE_SIZE * 2);
 	kfree(kmem);
+	kfree(zerokmem);
 
 	if (ret == 0) {
 		pr_info("tests passed.\n");
-- 
2.7.4

[toc] | [next] | [standalone]


#1579984

FromKees Cook <keescook@chromium.org>
Date2017-02-13 19:30 +0100
Message-ID<tatxT-7jT-15@gated-at.bofh.it>
In reply to#1579166
On Sat, Feb 11, 2017 at 10:13 PM, Hoeun Ryu <hoeun.ryu@gmail.com> wrote:
> In the hardend usercopy, the destination buffer will be zeroed if
> copy_from_user/get_user fails. This patch adds testcases for it.
> The destination buffer is set with non-zero value before illegal
> copy_from_user/get_user is executed and the buffer is compared to
> zero after usercopy is done.
>
> Signed-off-by: Hoeun Ryu <hoeun.ryu@gmail.com>

This looks great!

I'll adjust the commit slightly (the zeroing always happens,
regardless of hardened usercopy) and add it to my usercopy tree.

Thanks!

-Kees

-- 
Kees Cook
Pixel Security

[toc] | [prev] | [next] | [standalone]


#1579987

FromKees Cook <keescook@chromium.org>
Date2017-02-13 19:40 +0100
Message-ID<tatHA-7nG-19@gated-at.bofh.it>
In reply to#1579166
On Sat, Feb 11, 2017 at 10:13 PM, Hoeun Ryu <hoeun.ryu@gmail.com> wrote:
> In the hardend usercopy, the destination buffer will be zeroed if
> copy_from_user/get_user fails. This patch adds testcases for it.
> The destination buffer is set with non-zero value before illegal
> copy_from_user/get_user is executed and the buffer is compared to
> zero after usercopy is done.
>
> Signed-off-by: Hoeun Ryu <hoeun.ryu@gmail.com>
> ---
>  lib/test_user_copy.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>
> diff --git a/lib/test_user_copy.c b/lib/test_user_copy.c
> index 0ecef3e..54bd898 100644
> --- a/lib/test_user_copy.c
> +++ b/lib/test_user_copy.c
> @@ -41,11 +41,18 @@ static int __init test_user_copy_init(void)
>         char *bad_usermem;
>         unsigned long user_addr;
>         unsigned long value = 0x5A;
> +       char *zerokmem;
>
>         kmem = kmalloc(PAGE_SIZE * 2, GFP_KERNEL);
>         if (!kmem)
>                 return -ENOMEM;
>
> +       zerokmem = kzalloc(PAGE_SIZE * 2, GFP_KERNEL);
> +       if (!zerokmem) {
> +               kfree(kmem);
> +               return -ENOMEM;
> +       }
> +
>         user_addr = vm_mmap(NULL, 0, PAGE_SIZE * 2,
>                             PROT_READ | PROT_WRITE | PROT_EXEC,
>                             MAP_ANONYMOUS | MAP_PRIVATE, 0);
> @@ -69,25 +76,35 @@ static int __init test_user_copy_init(void)
>                     "legitimate put_user failed");
>
>         /* Invalid usage: none of these should succeed. */
> +       memset(kmem, 0x5A, PAGE_SIZE);
>         ret |= test(!copy_from_user(kmem, (char __user *)(kmem + PAGE_SIZE),
>                                     PAGE_SIZE),
>                     "illegal all-kernel copy_from_user passed");
> +       ret |= test(memcmp(zerokmem, kmem, PAGE_SIZE),
> +                   "zeroing failure for illegal all-kernel copy_from_user");
> +       memset(bad_usermem, 0x5A, PAGE_SIZE);

Oh, actually, ha-ha: this isn't legal: it's a direct copy from kernel
to userspace. :) This needs a copy_to_user()... (and same for the
memcmp...)

>         ret |= test(!copy_from_user(bad_usermem, (char __user *)kmem,
>                                     PAGE_SIZE),
>                     "illegal reversed copy_from_user passed");
> +       ret |= test(memcmp(zerokmem, bad_usermem, PAGE_SIZE),
> +                   "zeroing failure for illegal reversed copy_from_user");
>         ret |= test(!copy_to_user((char __user *)kmem, kmem + PAGE_SIZE,
>                                   PAGE_SIZE),
>                     "illegal all-kernel copy_to_user passed");
>         ret |= test(!copy_to_user((char __user *)kmem, bad_usermem,
>                                   PAGE_SIZE),
>                     "illegal reversed copy_to_user passed");
> +       memset(kmem, 0x5A, PAGE_SIZE);
>         ret |= test(!get_user(value, (unsigned long __user *)kmem),
>                     "illegal get_user passed");
> +       ret |= test(memcmp(zerokmem, kmem, sizeof(value)),
> +                   "zeroing failure for illegal get_user");
>         ret |= test(!put_user(value, (unsigned long __user *)kmem),
>                     "illegal put_user passed");
>
>         vm_munmap(user_addr, PAGE_SIZE * 2);
>         kfree(kmem);
> +       kfree(zerokmem);
>
>         if (ret == 0) {
>                 pr_info("tests passed.\n");
> --
> 2.7.4
>

Can you respin this?

-Kees

-- 
Kees Cook
Pixel Security

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web