2016-04-13 11:20:32

by Alexander Potapenko

[permalink] [raw]
Subject: [PATCH v2 1/2] mm, kasan: don't call kasan_krealloc() from ksize().

Instead of calling kasan_krealloc(), which replaces the memory allocation
stack ID (if stack depot is used), just unpoison the whole memory chunk.

Signed-off-by: Alexander Potapenko <[email protected]>
---
v2: - splitted v1 into two patches
---
mm/slab.c | 2 +-
mm/slub.c | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/mm/slab.c b/mm/slab.c
index 17e2848..de46319 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -4324,7 +4324,7 @@ size_t ksize(const void *objp)
/* We assume that ksize callers could use the whole allocated area,
* so we need to unpoison this area.
*/
- kasan_krealloc(objp, size, GFP_NOWAIT);
+ kasan_unpoison_shadow(objp, size);

return size;
}
diff --git a/mm/slub.c b/mm/slub.c
index 4dbb109e..62194e2 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3635,8 +3635,9 @@ size_t ksize(const void *object)
{
size_t size = __ksize(object);
/* We assume that ksize callers could use whole allocated area,
- so we need unpoison this area. */
- kasan_krealloc(object, size, GFP_NOWAIT);
+ * so we need to unpoison this area.
+ */
+ kasan_unpoison_shadow(object, size);
return size;
}
EXPORT_SYMBOL(ksize);
--
2.8.0.rc3.226.g39d4020


2016-04-13 11:21:08

by Alexander Potapenko

[permalink] [raw]
Subject: [PATCH v2 2/2] mm, kasan: add a ksize() test

Add a test that makes sure ksize() unpoisons the whole chunk.

Signed-off-by: Alexander Potapenko <[email protected]>
---
v2: - splitted v1 into two patches
---
lib/test_kasan.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/lib/test_kasan.c b/lib/test_kasan.c
index 82169fb..48e5a0b 100644
--- a/lib/test_kasan.c
+++ b/lib/test_kasan.c
@@ -344,6 +344,25 @@ static noinline void __init kasan_stack_oob(void)
*(volatile char *)p;
}

+static noinline void __init ksize_unpoisons_memory(void)
+{
+ char *ptr;
+ size_t size = 123, real_size = size;
+
+ pr_info("ksize() unpoisons the whole allocated chunk\n");
+ ptr = kmalloc(size, GFP_KERNEL);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+ real_size = ksize(ptr);
+ /* This access doesn't trigger an error. */
+ ptr[size] = 'x';
+ /* This one does. */
+ ptr[real_size] = 'y';
+ kfree(ptr);
+}
+
static int __init kmalloc_tests_init(void)
{
kmalloc_oob_right();
@@ -367,6 +386,7 @@ static int __init kmalloc_tests_init(void)
kmem_cache_oob();
kasan_stack_oob();
kasan_global_oob();
+ ksize_unpoisons_memory();
return -EAGAIN;
}

--
2.8.0.rc3.226.g39d4020

2016-04-15 15:59:13

by Andrey Ryabinin

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] mm, kasan: add a ksize() test



On 04/13/2016 02:20 PM, Alexander Potapenko wrote:
> Add a test that makes sure ksize() unpoisons the whole chunk.
>
> Signed-off-by: Alexander Potapenko <[email protected]>

Acked-by: Andrey Ryabinin <[email protected]>

> ---
> v2: - splitted v1 into two patches
> ---
> lib/test_kasan.c | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/lib/test_kasan.c b/lib/test_kasan.c
> index 82169fb..48e5a0b 100644
> --- a/lib/test_kasan.c
> +++ b/lib/test_kasan.c
> @@ -344,6 +344,25 @@ static noinline void __init kasan_stack_oob(void)
> *(volatile char *)p;
> }
>
> +static noinline void __init ksize_unpoisons_memory(void)
> +{
> + char *ptr;
> + size_t size = 123, real_size = size;
> +
> + pr_info("ksize() unpoisons the whole allocated chunk\n");
> + ptr = kmalloc(size, GFP_KERNEL);
> + if (!ptr) {
> + pr_err("Allocation failed\n");
> + return;
> + }
> + real_size = ksize(ptr);
> + /* This access doesn't trigger an error. */
> + ptr[size] = 'x';
> + /* This one does. */
> + ptr[real_size] = 'y';
> + kfree(ptr);
> +}
> +
> static int __init kmalloc_tests_init(void)
> {
> kmalloc_oob_right();
> @@ -367,6 +386,7 @@ static int __init kmalloc_tests_init(void)
> kmem_cache_oob();
> kasan_stack_oob();
> kasan_global_oob();
> + ksize_unpoisons_memory();
> return -EAGAIN;
> }
>
>

2016-04-15 16:14:28

by Andrey Ryabinin

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] mm, kasan: don't call kasan_krealloc() from ksize().



On 04/13/2016 02:20 PM, Alexander Potapenko wrote:
> Instead of calling kasan_krealloc(), which replaces the memory allocation
> stack ID (if stack depot is used), just unpoison the whole memory chunk.
>
> Signed-off-by: Alexander Potapenko <[email protected]>

Acked-by: Andrey Ryabinin <[email protected]>

> ---
> v2: - splitted v1 into two patches
> ---
> mm/slab.c | 2 +-
> mm/slub.c | 5 +++--
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/mm/slab.c b/mm/slab.c
> index 17e2848..de46319 100644
> --- a/mm/slab.c
> +++ b/mm/slab.c
> @@ -4324,7 +4324,7 @@ size_t ksize(const void *objp)
> /* We assume that ksize callers could use the whole allocated area,
> * so we need to unpoison this area.
> */
> - kasan_krealloc(objp, size, GFP_NOWAIT);
> + kasan_unpoison_shadow(objp, size);
>
> return size;
> }
> diff --git a/mm/slub.c b/mm/slub.c
> index 4dbb109e..62194e2 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -3635,8 +3635,9 @@ size_t ksize(const void *object)
> {
> size_t size = __ksize(object);
> /* We assume that ksize callers could use whole allocated area,
> - so we need unpoison this area. */
> - kasan_krealloc(object, size, GFP_NOWAIT);
> + * so we need to unpoison this area.
> + */
> + kasan_unpoison_shadow(object, size);
> return size;
> }
> EXPORT_SYMBOL(ksize);
>

2016-04-22 21:33:01

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] mm, kasan: don't call kasan_krealloc() from ksize().

On Wed, 13 Apr 2016 13:20:09 +0200 Alexander Potapenko <[email protected]> wrote:

> Instead of calling kasan_krealloc(), which replaces the memory allocation
> stack ID (if stack depot is used), just unpoison the whole memory chunk.

I don't understand why these two patches exist. Bugfix? Cleanup?
Optimization?


I had to change kmalloc_tests_init() a bit due to
mm-kasan-initial-memory-quarantine-implementation.patch:

kasan_stack_oob();
kasan_global_oob();
#ifdef CONFIG_SLAB
kasan_quarantine_cache();
#endif
+ ksize_unpoisons_memory();
return -EAGAIN;
}

Please check.

2016-04-28 11:38:39

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] mm, kasan: don't call kasan_krealloc() from ksize().

On Fri, Apr 22, 2016 at 11:32 PM, Andrew Morton
<[email protected]> wrote:
> On Wed, 13 Apr 2016 13:20:09 +0200 Alexander Potapenko <[email protected]> wrote:
>
>> Instead of calling kasan_krealloc(), which replaces the memory allocation
>> stack ID (if stack depot is used), just unpoison the whole memory chunk.
>
> I don't understand why these two patches exist. Bugfix? Cleanup?
> Optimization?
It's incorrect to call kasan_krealloc() from ksize(), because the
former may touch the allocation metadata (it does so for the SLAB
allocator).
Yes, this is a bugfix.
>
> I had to change kmalloc_tests_init() a bit due to
> mm-kasan-initial-memory-quarantine-implementation.patch:
>
> kasan_stack_oob();
> kasan_global_oob();
> #ifdef CONFIG_SLAB
> kasan_quarantine_cache();
> #endif
> + ksize_unpoisons_memory();
> return -EAGAIN;
> }
>
> Please check.
Ack.



--
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Matthew Scott Sucherman, Paul Terence Manicle
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg