linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Laura Abbott <laura@labbott.name>
To: Christoph Lameter <cl@linux.com>,
	Pekka Enberg <penberg@kernel.org>,
	David Rientjes <rientjes@google.com>,
	Joonsoo Kim <iamjoonsoo.kim@lge.com>,
	Andrew Morton <akpm@linux-foundation.org>
Cc: Laura Abbott <laura@labbott.name>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Kees Cook <keescook@chromium.org>,
	kernel-hardening@lists.openwall.com
Subject: [RFC][PATCH 2/7] slub: Add support for sanitization
Date: Mon, 21 Dec 2015 19:40:36 -0800	[thread overview]
Message-ID: <1450755641-7856-3-git-send-email-laura@labbott.name> (raw)
In-Reply-To: <1450755641-7856-1-git-send-email-laura@labbott.name>


Clearing of objects on free only happens when SLUB_DEBUG and poisoning
is enabled for caches. This is a potential source of security leaks;
sensitive information may remain around well after its normal life
time. Add support for sanitizing objects independent of debug features.
Sanitization can be configured on only the slow path or all paths.

All credit for the original work should be given to Brad Spengler and
the PaX Team.

Signed-off-by: Laura Abbott <laura@labbott.name>
---
 mm/slub.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 89 insertions(+), 1 deletion(-)

diff --git a/mm/slub.c b/mm/slub.c
index 4699751..a02e1e7 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -220,6 +220,15 @@ static inline void stat(const struct kmem_cache *s, enum stat_item si)
 #endif
 }
 
+static inline bool should_sanitize_slab(const struct kmem_cache *s)
+{
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+		return !(s->flags & SLAB_NO_SANITIZE);
+#else
+		return false;
+#endif
+}
+
 /********************************************************************
  * 			Core slab cache functions
  *******************************************************************/
@@ -286,6 +295,9 @@ static inline int slab_index(void *p, struct kmem_cache *s, void *addr)
 
 static inline size_t slab_ksize(const struct kmem_cache *s)
 {
+	if (should_sanitize_slab(s))
+		return s->object_size;
+
 #ifdef CONFIG_SLUB_DEBUG
 	/*
 	 * Debugging requires use of the padding between object
@@ -1263,6 +1275,66 @@ static inline void dec_slabs_node(struct kmem_cache *s, int node,
 
 #endif /* CONFIG_SLUB_DEBUG */
 
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+static void __sanitize_object(struct kmem_cache *s, void *p)
+{
+	memset(p, SLAB_MEMORY_SANITIZE_VALUE, s->object_size);
+	if (s->ctor)
+		s->ctor(p);
+}
+
+static void sanitize_objects(struct kmem_cache *s, void *head, void *tail,
+				int cnt)
+{
+	int i = 1;
+	void *p = head;
+
+	do {
+		if (i > cnt)
+			BUG();
+
+		__sanitize_object(s, p);
+		i++;
+	} while (p != tail && (p = get_freepointer(s, p)));
+}
+
+
+static void sanitize_slow_path(struct kmem_cache *s, void *head, void *tail,
+				int cnt)
+{
+	if (sanitize_slab != SLAB_SANITIZE_PARTIAL_SLOWPATH)
+		return;
+
+	if (!should_sanitize_slab(s))
+		return;
+
+	sanitize_objects(s, head, tail, cnt);
+}
+
+static void sanitize_object(struct kmem_cache *s, void *p)
+{
+	if (sanitize_slab != SLAB_SANITIZE_FULL &&
+	    sanitize_slab != SLAB_SANITIZE_PARTIAL)
+		return;
+
+	if (!should_sanitize_slab(s))
+		return;
+
+	__sanitize_object(s, p);
+}
+#else
+static void sanitize_slow_path(struct kmem_cache *s, void *head, void *tail,
+				int cnt)
+{
+	return;
+}
+
+static void sanitize_object(struct kmem_cache *s, void *p)
+{
+	return;
+}
+#endif
+
 /*
  * Hooks for other subsystems that check memory allocations. In a typical
  * production configuration these hooks all should produce no code at all.
@@ -1311,6 +1383,7 @@ static inline void slab_post_alloc_hook(struct kmem_cache *s, gfp_t flags,
 
 static inline void slab_free_hook(struct kmem_cache *s, void *x)
 {
+	sanitize_object(s, x);
 	kmemleak_free_recursive(x, s->flags);
 
 	/*
@@ -1345,7 +1418,8 @@ static inline void slab_free_freelist_hook(struct kmem_cache *s,
 	defined(CONFIG_LOCKDEP)	||		\
 	defined(CONFIG_DEBUG_KMEMLEAK) ||	\
 	defined(CONFIG_DEBUG_OBJECTS_FREE) ||	\
-	defined(CONFIG_KASAN)
+	defined(CONFIG_KASAN) || \
+	defined(CONFIG_SLAB_MEMORY_SANITIZE)
 
 	void *object = head;
 	void *tail_obj = tail ? : head;
@@ -2645,6 +2719,8 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
 
 	stat(s, FREE_SLOWPATH);
 
+	sanitize_slow_path(s, head, tail, cnt);
+
 	if (kmem_cache_debug(s) &&
 	    !(n = free_debug_processing(s, page, head, tail, cnt,
 					addr, &flags)))
@@ -3262,6 +3338,7 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
 	s->inuse = size;
 
 	if (((flags & (SLAB_DESTROY_BY_RCU | SLAB_POISON)) ||
+		should_sanitize_slab(s) ||
 		s->ctor)) {
 		/*
 		 * Relocate free pointer after the object if it is not
@@ -4787,6 +4864,14 @@ static ssize_t cache_dma_show(struct kmem_cache *s, char *buf)
 SLAB_ATTR_RO(cache_dma);
 #endif
 
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+static ssize_t sanitize_show(struct kmem_cache *s, char *buf)
+{
+	return sprintf(buf, "%d\n", should_sanitize_slab(s));
+}
+SLAB_ATTR_RO(sanitize);
+#endif
+
 static ssize_t destroy_by_rcu_show(struct kmem_cache *s, char *buf)
 {
 	return sprintf(buf, "%d\n", !!(s->flags & SLAB_DESTROY_BY_RCU));
@@ -5129,6 +5214,9 @@ static struct attribute *slab_attrs[] = {
 #ifdef CONFIG_ZONE_DMA
 	&cache_dma_attr.attr,
 #endif
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+	&sanitize_attr.attr,
+#endif
 #ifdef CONFIG_NUMA
 	&remote_node_defrag_ratio_attr.attr,
 #endif
-- 
2.5.0

--
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>

  parent reply	other threads:[~2015-12-22  3:41 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-22  3:40 [RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX Laura Abbott
2015-12-22  3:40 ` [RFC][PATCH 1/7] mm/slab_common.c: Add common support for slab saniziation Laura Abbott
2015-12-22 20:48   ` Vlastimil Babka
2016-01-06  0:17     ` Kees Cook
2016-01-06  2:06       ` Laura Abbott
2016-01-06  0:19   ` Kees Cook
2015-12-22  3:40 ` Laura Abbott [this message]
2015-12-22  3:40 ` [RFC][PATCH 3/7] slab: Add support for sanitization Laura Abbott
2015-12-22  3:40 ` [RFC][PATCH 4/7] slob: " Laura Abbott
2015-12-22  3:40 ` [RFC][PATCH 5/7] mm: Mark several cases as SLAB_NO_SANITIZE Laura Abbott
2016-01-06  0:21   ` Kees Cook
2016-01-06  2:11     ` Laura Abbott
2015-12-22  3:40 ` [RFC][PATCH 6/7] mm: Add Kconfig option for slab sanitization Laura Abbott
2015-12-22  9:33   ` [kernel-hardening] " Mathias Krause
2015-12-22 17:51     ` Laura Abbott
2015-12-22 18:37       ` Mathias Krause
2015-12-22 19:18         ` Laura Abbott
2015-12-22 20:01         ` Christoph Lameter
2015-12-22 20:06           ` Mathias Krause
2015-12-22 14:57   ` Dave Hansen
2015-12-22 16:25     ` Christoph Lameter
2015-12-22 17:22       ` Dave Hansen
2015-12-22 17:24         ` Christoph Lameter
2015-12-22 17:28           ` Dave Hansen
2015-12-22 18:08             ` Christoph Lameter
2015-12-22 18:19               ` Dave Hansen
2015-12-22 19:13                 ` Laura Abbott
2015-12-22 19:32                   ` Dave Hansen
2016-01-06  0:29                   ` Kees Cook
2016-01-06  2:46                     ` Laura Abbott
2015-12-22  3:40 ` [RFC][PATCH 7/7] lkdtm: Add READ_AFTER_FREE test Laura Abbott
2016-01-06  0:15   ` Kees Cook
2016-01-06  2:49     ` Laura Abbott
2015-12-22 16:08 ` [RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX Christoph Lameter
2015-12-22 16:15   ` [kernel-hardening] " Dave Hansen
2015-12-22 16:38   ` Daniel Micay
2015-12-22 20:04   ` Laura Abbott
2016-01-06  0:09     ` Kees Cook
2016-01-06  3:17       ` Laura Abbott
2016-01-07 16:26         ` Christoph Lameter
2016-01-08  1:23           ` Laura Abbott
2016-01-08 14:07             ` Christoph Lameter
2016-01-14  3:49               ` Laura Abbott
2016-01-21  3:35                 ` Laura Abbott
2016-01-21 15:39                   ` Christoph Lameter

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=1450755641-7856-3-git-send-email-laura@labbott.name \
    --to=laura@labbott.name \
    --cc=akpm@linux-foundation.org \
    --cc=cl@linux.com \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=penberg@kernel.org \
    --cc=rientjes@google.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;
as well as URLs for NNTP newsgroup(s).