Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1579166 > unrolled thread
| Started by | Hoeun Ryu <hoeun.ryu@gmail.com> |
|---|---|
| First post | 2017-02-12 07:20 +0100 |
| Last post | 2017-02-13 19:40 +0100 |
| Articles | 3 — 2 participants |
Back to article view | Back to linux.kernel
[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
| From | Hoeun Ryu <hoeun.ryu@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Kees Cook <keescook@chromium.org> |
|---|---|
| Date | 2017-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]
| From | Kees Cook <keescook@chromium.org> |
|---|---|
| Date | 2017-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