From: "Liu, XinwuX" <xinwux.liu@intel.com>
To: "catalin.marinas@arm.com" <catalin.marinas@arm.com>,
"cl@linux-foundation.org" <cl@linux-foundation.org>,
"penberg@kernel.org" <penberg@kernel.org>,
"mpm@selenic.com" <mpm@selenic.com>
Cc: "linux-mm@kvack.org" <linux-mm@kvack.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"yanmin_zhang@linux.intel.com" <yanmin_zhang@linux.intel.com>,
"He, Bo" <bo.he@intel.com>, "Chen, Lin Z" <lin.z.chen@intel.com>
Subject: [PATCH] slub/slab: fix kmemleak didn't work on some case
Date: Mon, 8 Jun 2015 05:14:32 +0000 [thread overview]
Message-ID: <99C214DF91337140A8D774E25DF6CD5FC89DA2@shsmsx102.ccr.corp.intel.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 6183 bytes --]
when kernel uses kmalloc to allocate memory, slub/slab will find
a suitable kmem_cache. Ususally the cache's object size is often
greater than requested size. There is unused space which contains
dirty data. These dirty data might have pointers pointing to a block
of leaked memory. Kernel wouldn't consider this memory as leaked when
scanning kmemleak object.
The patch fixes it by clearing the unused memory.
Signed-off-by: Liu, XinwuX <xinwux.liu@intel.com>
Signed-off-by: Chen Lin Z <lin.z.chen@intel.com>
---
mm/slab.c | 22 +++++++++++++++++++++-
mm/slub.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/mm/slab.c b/mm/slab.c
index 7eb38dd..ef25e7d 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3423,6 +3423,12 @@ kmem_cache_alloc_trace(struct kmem_cache *cachep, gfp_t flags, size_t size)
ret = slab_alloc(cachep, flags, _RET_IP_);
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ int delta = cachep->object_size - size;
+
+ if (ret && likely(!(flags & __GFP_ZERO)) && (delta > 0))
+ memset((void *)((char *)ret + size), 0, delta);
+#endif
trace_kmalloc(_RET_IP_, ret,
size, cachep->size, flags);
return ret;
@@ -3476,11 +3482,19 @@ static __always_inline void *
__do_kmalloc_node(size_t size, gfp_t flags, int node, unsigned long caller)
{
struct kmem_cache *cachep;
+ void *ret;
cachep = kmalloc_slab(size, flags);
if (unlikely(ZERO_OR_NULL_PTR(cachep)))
return cachep;
- return kmem_cache_alloc_node_trace(cachep, flags, node, size);
+ ret = kmem_cache_alloc_node_trace(cachep, flags, node, size);
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ int delta = cachep->object_size - size;
+
+ if (ret && likely(!(flags & __GFP_ZERO)) && (delta > 0))
+ memset((void *)((char *)ret + size), 0, delta);
+#endif
+ return ret;
}
void *__kmalloc_node(size_t size, gfp_t flags, int node)
@@ -3513,6 +3527,12 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
if (unlikely(ZERO_OR_NULL_PTR(cachep)))
return cachep;
ret = slab_alloc(cachep, flags, caller);
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ int delta = cachep->object_size - size;
+
+ if (ret && likely(!(flags & __GFP_ZERO)) && (delta > 0))
+ memset((void *)((char *)ret + size), 0, delta);
+#endif
trace_kmalloc(caller, ret,
size, cachep->size, flags);
diff --git a/mm/slub.c b/mm/slub.c
index 54c0876..b53d9af 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2530,6 +2530,12 @@ EXPORT_SYMBOL(kmem_cache_alloc);
void *kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size)
{
void *ret = slab_alloc(s, gfpflags, _RET_IP_);
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ int delta = s->object_size - size;
+
+ if (ret && likely(!(gfpflags & __GFP_ZERO)) && (delta > 0))
+ memset((void *)((char *)ret + size), 0, delta);
+#endif
trace_kmalloc(_RET_IP_, ret, size, s->size, gfpflags);
kasan_kmalloc(s, ret, size);
return ret;
@@ -2556,6 +2562,12 @@ void *kmem_cache_alloc_node_trace(struct kmem_cache *s,
{
void *ret = slab_alloc_node(s, gfpflags, node, _RET_IP_);
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ int delta = s->object_size - size;
+
+ if (ret && likely(!(gfpflags & __GFP_ZERO)) && (delta > 0))
+ memset((void *)((char *)ret + size), 0, delta);
+#endif
trace_kmalloc_node(_RET_IP_, ret,
size, s->size, gfpflags, node);
@@ -3316,6 +3328,12 @@ void *__kmalloc(size_t size, gfp_t flags)
return s;
ret = slab_alloc(s, flags, _RET_IP_);
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ int delta = s->object_size - size;
+
+ if (ret && likely(!(flags & __GFP_ZERO)) && (delta > 0))
+ memset((void *)((char *)ret + size), 0, delta);
+#endif
trace_kmalloc(_RET_IP_, ret, size, s->size, flags);
@@ -3361,6 +3379,12 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node)
return s;
ret = slab_alloc_node(s, flags, node, _RET_IP_);
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ int delta = s->object_size - size;
+
+ if (ret && likely(!(flags & __GFP_ZERO)) && (delta > 0))
+ memset((void *)((char *)ret + size), 0, delta);
+#endif
trace_kmalloc_node(_RET_IP_, ret, size, s->size, flags, node);
@@ -3819,7 +3843,12 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
return s;
ret = slab_alloc(s, gfpflags, caller);
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ int delta = s->object_size - size;
+ if (ret && likely(!(gfpflags & __GFP_ZERO)) && (delta > 0))
+ memset((void *)((char *)ret + size), 0, delta);
+#endif
/* Honor the call site pointer we received. */
trace_kmalloc(caller, ret, size, s->size, gfpflags);
@@ -3849,6 +3878,12 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
return s;
ret = slab_alloc_node(s, gfpflags, node, caller);
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ int delta = s->object_size - size;
+
+ if (ret && likely(!(gfpflags & __GFP_ZERO)) && (delta > 0))
+ memset((void *)((char *)ret + size), 0, delta);
+#endif
/* Honor the call site pointer we received. */
trace_kmalloc_node(caller, ret, size, s->size, gfpflags, node);
--
1.9.1
[-- Attachment #2: Type: text/html, Size: 20161 bytes --]
next reply other threads:[~2015-06-08 5:15 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-08 5:14 Liu, XinwuX [this message]
2015-06-08 9:38 ` Christoph Lameter
2015-06-08 10:13 ` Catalin Marinas
2015-06-09 8:10 ` Zhang, Yanmin
2015-06-09 15:03 ` Catalin Marinas
2015-06-10 7:45 ` Zhang, Yanmin
2015-06-10 9:48 ` Catalin Marinas
2015-06-11 8:18 ` Liu, XinwuX
2015-06-08 10:03 ` Catalin Marinas
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=99C214DF91337140A8D774E25DF6CD5FC89DA2@shsmsx102.ccr.corp.intel.com \
--to=xinwux.liu@intel.com \
--cc=bo.he@intel.com \
--cc=catalin.marinas@arm.com \
--cc=cl@linux-foundation.org \
--cc=lin.z.chen@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mpm@selenic.com \
--cc=penberg@kernel.org \
--cc=yanmin_zhang@linux.intel.com \
/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