All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrey Ryabinin <aryabinin@virtuozzo.com>
To: Alexander Potapenko <glider@google.com>,
	adech.fo@gmail.com, cl@linux.com, dvyukov@google.com,
	akpm@linux-foundation.org, rostedt@goodmis.org,
	iamjoonsoo.kim@lge.com, js1304@gmail.com, kcc@google.com,
	kuthonuzo.luruo@hpe.com
Cc: kasan-dev@googlegroups.com, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] mm: kasan: don't touch metadata in kasan_[un]poison_element()
Date: Wed, 1 Jun 2016 19:22:14 +0300	[thread overview]
Message-ID: <574F0BB6.1040400@virtuozzo.com> (raw)
In-Reply-To: <1464785606-20349-1-git-send-email-glider@google.com>



On 06/01/2016 03:53 PM, Alexander Potapenko wrote:
> To avoid draining the mempools, KASAN shouldn't put the mempool elements
> into the quarantine upon mempool_free().

Correct, but unfortunately this patch doesn't fix that.

> It shouldn't store
> allocation/deallocation stacks upon mempool_alloc()/mempool_free() either.

Why not?

> Therefore make kasan_[un]poison_element() just change the shadow memory,
> not the metadata.
> 
> Signed-off-by: Alexander Potapenko <glider@google.com>
> Reported-by: Kuthonuzo Luruo <kuthonuzo.luruo@hpe.com>
> ---

[...]

> +void kasan_slab_alloc(struct kmem_cache *cache, void *object,
> +			bool just_unpoison, gfp_t flags)
>  {
> -	kasan_kmalloc(cache, object, cache->object_size, flags);
> +	if (just_unpoison)

This set to 'false' in all call sites.

> +		kasan_unpoison_shadow(object, cache->object_size);
> +	else
> +		kasan_kmalloc(cache, object, cache->object_size, flags);
>  }
>  
>  void kasan_poison_slab_free(struct kmem_cache *cache, void *object)
> @@ -611,6 +615,31 @@ void kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags)
>  		KASAN_PAGE_REDZONE);
>  }
>  
> +void kasan_unpoison_kmalloc(const void *object, size_t size, gfp_t flags)
> +{
> +	struct page *page;
> +	unsigned long redzone_start;
> +	unsigned long redzone_end;
> +
> +	if (unlikely(object == ZERO_SIZE_PTR) || (object == NULL))
> +		return;
> +
> +	page = virt_to_head_page(object);
> +	redzone_start = round_up((unsigned long)(object + size),
> +				KASAN_SHADOW_SCALE_SIZE);
> +
> +	if (unlikely(!PageSlab(page)))
> +		redzone_end = (unsigned long)object +
> +			(PAGE_SIZE << compound_order(page));
> +	else
> +		redzone_end = round_up(
> +			(unsigned long)object + page->slab_cache->object_size,
> +			KASAN_SHADOW_SCALE_SIZE);
> +	kasan_unpoison_shadow(object, size);
> +	kasan_poison_shadow((void *)redzone_start, redzone_end - redzone_start,
> +		KASAN_KMALLOC_REDZONE);
> +}
> +
>  void kasan_krealloc(const void *object, size_t size, gfp_t flags)
>  {
>  	struct page *page;
> @@ -636,7 +665,20 @@ void kasan_kfree(void *ptr)
>  		kasan_poison_shadow(ptr, PAGE_SIZE << compound_order(page),
>  				KASAN_FREE_PAGE);
>  	else
> -		kasan_slab_free(page->slab_cache, ptr);
> +		kasan_poison_slab_free(page->slab_cache, ptr);
> +}
> +
> +void kasan_poison_kfree(void *ptr)

Unused

> +{
> +	struct page *page;
> +
> +	page = virt_to_head_page(ptr);
> +
> +	if (unlikely(!PageSlab(page)))
> +		kasan_poison_shadow(ptr, PAGE_SIZE << compound_order(page),
> +				KASAN_FREE_PAGE);
> +	else
> +		kasan_poison_slab_free(page->slab_cache, ptr);
>  }
>  
>  void kasan_kfree_large(const void *ptr)
> diff --git a/mm/mempool.c b/mm/mempool.c
> index 9e075f8..bcd48c6 100644
> --- a/mm/mempool.c
> +++ b/mm/mempool.c
> @@ -115,9 +115,10 @@ static void kasan_poison_element(mempool_t *pool, void *element)
>  static void kasan_unpoison_element(mempool_t *pool, void *element, gfp_t flags)
>  {
>  	if (pool->alloc == mempool_alloc_slab)
> -		kasan_slab_alloc(pool->pool_data, element, flags);
> +		kasan_slab_alloc(pool->pool_data, element,
> +				/*just_unpoison*/ false, flags);
>  	if (pool->alloc == mempool_kmalloc)
> -		kasan_krealloc(element, (size_t)pool->pool_data, flags);
> +		kasan_unpoison_kmalloc(element, (size_t)pool->pool_data, flags);

I think, that the current code here is fine.
We only need to fix kasan_poison_element() which calls kasan_kfree() that puts objects into quarantine.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

WARNING: multiple messages have this Message-ID (diff)
From: Andrey Ryabinin <aryabinin@virtuozzo.com>
To: Alexander Potapenko <glider@google.com>, <adech.fo@gmail.com>,
	<cl@linux.com>, <dvyukov@google.com>, <akpm@linux-foundation.org>,
	<rostedt@goodmis.org>, <iamjoonsoo.kim@lge.com>,
	<js1304@gmail.com>, <kcc@google.com>, <kuthonuzo.luruo@hpe.com>
Cc: <kasan-dev@googlegroups.com>, <linux-mm@kvack.org>,
	<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] mm: kasan: don't touch metadata in kasan_[un]poison_element()
Date: Wed, 1 Jun 2016 19:22:14 +0300	[thread overview]
Message-ID: <574F0BB6.1040400@virtuozzo.com> (raw)
In-Reply-To: <1464785606-20349-1-git-send-email-glider@google.com>



On 06/01/2016 03:53 PM, Alexander Potapenko wrote:
> To avoid draining the mempools, KASAN shouldn't put the mempool elements
> into the quarantine upon mempool_free().

Correct, but unfortunately this patch doesn't fix that.

> It shouldn't store
> allocation/deallocation stacks upon mempool_alloc()/mempool_free() either.

Why not?

> Therefore make kasan_[un]poison_element() just change the shadow memory,
> not the metadata.
> 
> Signed-off-by: Alexander Potapenko <glider@google.com>
> Reported-by: Kuthonuzo Luruo <kuthonuzo.luruo@hpe.com>
> ---

[...]

> +void kasan_slab_alloc(struct kmem_cache *cache, void *object,
> +			bool just_unpoison, gfp_t flags)
>  {
> -	kasan_kmalloc(cache, object, cache->object_size, flags);
> +	if (just_unpoison)

This set to 'false' in all call sites.

> +		kasan_unpoison_shadow(object, cache->object_size);
> +	else
> +		kasan_kmalloc(cache, object, cache->object_size, flags);
>  }
>  
>  void kasan_poison_slab_free(struct kmem_cache *cache, void *object)
> @@ -611,6 +615,31 @@ void kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags)
>  		KASAN_PAGE_REDZONE);
>  }
>  
> +void kasan_unpoison_kmalloc(const void *object, size_t size, gfp_t flags)
> +{
> +	struct page *page;
> +	unsigned long redzone_start;
> +	unsigned long redzone_end;
> +
> +	if (unlikely(object == ZERO_SIZE_PTR) || (object == NULL))
> +		return;
> +
> +	page = virt_to_head_page(object);
> +	redzone_start = round_up((unsigned long)(object + size),
> +				KASAN_SHADOW_SCALE_SIZE);
> +
> +	if (unlikely(!PageSlab(page)))
> +		redzone_end = (unsigned long)object +
> +			(PAGE_SIZE << compound_order(page));
> +	else
> +		redzone_end = round_up(
> +			(unsigned long)object + page->slab_cache->object_size,
> +			KASAN_SHADOW_SCALE_SIZE);
> +	kasan_unpoison_shadow(object, size);
> +	kasan_poison_shadow((void *)redzone_start, redzone_end - redzone_start,
> +		KASAN_KMALLOC_REDZONE);
> +}
> +
>  void kasan_krealloc(const void *object, size_t size, gfp_t flags)
>  {
>  	struct page *page;
> @@ -636,7 +665,20 @@ void kasan_kfree(void *ptr)
>  		kasan_poison_shadow(ptr, PAGE_SIZE << compound_order(page),
>  				KASAN_FREE_PAGE);
>  	else
> -		kasan_slab_free(page->slab_cache, ptr);
> +		kasan_poison_slab_free(page->slab_cache, ptr);
> +}
> +
> +void kasan_poison_kfree(void *ptr)

Unused

> +{
> +	struct page *page;
> +
> +	page = virt_to_head_page(ptr);
> +
> +	if (unlikely(!PageSlab(page)))
> +		kasan_poison_shadow(ptr, PAGE_SIZE << compound_order(page),
> +				KASAN_FREE_PAGE);
> +	else
> +		kasan_poison_slab_free(page->slab_cache, ptr);
>  }
>  
>  void kasan_kfree_large(const void *ptr)
> diff --git a/mm/mempool.c b/mm/mempool.c
> index 9e075f8..bcd48c6 100644
> --- a/mm/mempool.c
> +++ b/mm/mempool.c
> @@ -115,9 +115,10 @@ static void kasan_poison_element(mempool_t *pool, void *element)
>  static void kasan_unpoison_element(mempool_t *pool, void *element, gfp_t flags)
>  {
>  	if (pool->alloc == mempool_alloc_slab)
> -		kasan_slab_alloc(pool->pool_data, element, flags);
> +		kasan_slab_alloc(pool->pool_data, element,
> +				/*just_unpoison*/ false, flags);
>  	if (pool->alloc == mempool_kmalloc)
> -		kasan_krealloc(element, (size_t)pool->pool_data, flags);
> +		kasan_unpoison_kmalloc(element, (size_t)pool->pool_data, flags);

I think, that the current code here is fine.
We only need to fix kasan_poison_element() which calls kasan_kfree() that puts objects into quarantine.

  reply	other threads:[~2016-06-01 16:21 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-01 12:53 [PATCH] mm: kasan: don't touch metadata in kasan_[un]poison_element() Alexander Potapenko
2016-06-01 12:53 ` Alexander Potapenko
2016-06-01 16:22 ` Andrey Ryabinin [this message]
2016-06-01 16:22   ` Andrey Ryabinin
2016-06-09 14:05   ` [PATCH] mm: mempool: kasan: don't poot mempool objects in quarantine Andrey Ryabinin
2016-06-09 14:05     ` Andrey Ryabinin
2016-06-09 15:20     ` Alexander Potapenko
2016-06-09 15:20       ` Alexander Potapenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=574F0BB6.1040400@virtuozzo.com \
    --to=aryabinin@virtuozzo.com \
    --cc=adech.fo@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=cl@linux.com \
    --cc=dvyukov@google.com \
    --cc=glider@google.com \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=js1304@gmail.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=kcc@google.com \
    --cc=kuthonuzo.luruo@hpe.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.