From: Kuthonuzo Luruo <kuthonuzo.luruo@hpe.com>
To: aryabinin@virtuozzo.com, glider@google.com, dvyukov@google.com
Cc: akpm@linux-foundation.org, kasan-dev@googlegroups.com,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
kuthonuzo.luruo@hpe.com
Subject: [PATCH] kasan: improve double-free detection
Date: Mon, 2 May 2016 15:19:20 +0530 [thread overview]
Message-ID: <20160502094920.GA3005@cherokee.in.rdlabs.hpecorp.net> (raw)
Hi Alexander/Andrey/Dmitry,
For your consideration/review. Thanks!
Kuthonuzo Luruo
Currently, KASAN may fail to detect concurrent deallocations of the same
object due to a race in kasan_slab_free(). This patch makes double-free
detection more reliable by atomically setting allocation state for object
to KASAN_STATE_QUARANTINE iff current state is KASAN_STATE_ALLOC.
Tested using a modified version of the 'slab_test' microbenchmark where
allocs occur on CPU 0; then all other CPUs concurrently attempt to free the
same object.
Signed-off-by: Kuthonuzo Luruo <kuthonuzo.luruo@hpe.com>
---
mm/kasan/kasan.c | 32 ++++++++++++++++++--------------
mm/kasan/kasan.h | 5 ++---
2 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c
index ef2e87b..4fc4e76 100644
--- a/mm/kasan/kasan.c
+++ b/mm/kasan/kasan.c
@@ -511,23 +511,28 @@ void kasan_poison_slab_free(struct kmem_cache *cache, void *object)
bool kasan_slab_free(struct kmem_cache *cache, void *object)
{
#ifdef CONFIG_SLAB
+ struct kasan_alloc_meta *alloc_info;
+ struct kasan_free_meta *free_info;
+
/* RCU slabs could be legally used after free within the RCU period */
if (unlikely(cache->flags & SLAB_DESTROY_BY_RCU))
return false;
- if (likely(cache->flags & SLAB_KASAN)) {
- struct kasan_alloc_meta *alloc_info =
- get_alloc_info(cache, object);
- struct kasan_free_meta *free_info =
- get_free_info(cache, object);
-
- switch (alloc_info->state) {
- case KASAN_STATE_ALLOC:
- alloc_info->state = KASAN_STATE_QUARANTINE;
- quarantine_put(free_info, cache);
- set_track(&free_info->track, GFP_NOWAIT);
- kasan_poison_slab_free(cache, object);
- return true;
+ if (unlikely(!(cache->flags & SLAB_KASAN)))
+ return false;
+
+ alloc_info = get_alloc_info(cache, object);
+
+ if (cmpxchg(&alloc_info->state, KASAN_STATE_ALLOC,
+ KASAN_STATE_QUARANTINE) == KASAN_STATE_ALLOC) {
+ free_info = get_free_info(cache, object);
+ quarantine_put(free_info, cache);
+ set_track(&free_info->track, GFP_NOWAIT);
+ kasan_poison_slab_free(cache, object);
+ return true;
+ }
+
+ switch (alloc_info->state) {
case KASAN_STATE_QUARANTINE:
case KASAN_STATE_FREE:
pr_err("Double free");
@@ -535,7 +540,6 @@ bool kasan_slab_free(struct kmem_cache *cache, void *object)
break;
default:
break;
- }
}
return false;
#else
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index 7da78a6..8c22a96 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -75,9 +75,8 @@ struct kasan_track {
struct kasan_alloc_meta {
struct kasan_track track;
- u32 state : 2; /* enum kasan_state */
- u32 alloc_size : 30;
- u32 reserved;
+ u32 state; /* enum kasan_state */
+ u32 alloc_size;
};
struct kasan_free_meta {
--
1.7.1
--
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>
next reply other threads:[~2016-05-02 9:49 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-02 9:49 Kuthonuzo Luruo [this message]
2016-05-02 10:09 ` Dmitry Vyukov
2016-05-02 11:30 ` Luruo, Kuthonuzo
2016-05-02 11:35 ` Dmitry Vyukov
2016-05-03 9:24 ` Luruo, Kuthonuzo
2016-05-03 17:50 ` Dmitry Vyukov
2016-05-07 10:21 ` Luruo, Kuthonuzo
2016-05-02 11:41 ` Dmitry Vyukov
2016-05-02 11:47 ` Alexander Potapenko
2016-05-03 7:58 ` Luruo, Kuthonuzo
2016-05-03 7:53 ` Luruo, Kuthonuzo
2016-05-03 17:42 ` Dmitry Vyukov
2016-05-04 20:13 ` Luruo, Kuthonuzo
2016-05-05 5:34 ` Dmitry Vyukov
2016-05-05 6:23 ` Luruo, Kuthonuzo
2016-05-05 6:55 ` Dmitry Vyukov
2016-05-07 8:56 ` Luruo, Kuthonuzo
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=20160502094920.GA3005@cherokee.in.rdlabs.hpecorp.net \
--to=kuthonuzo.luruo@hpe.com \
--cc=akpm@linux-foundation.org \
--cc=aryabinin@virtuozzo.com \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=kasan-dev@googlegroups.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox