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 1/7] mm/slab_common.c: Add common support for slab saniziation
Date: Mon, 21 Dec 2015 19:40:35 -0800	[thread overview]
Message-ID: <1450755641-7856-2-git-send-email-laura@labbott.name> (raw)
In-Reply-To: <1450755641-7856-1-git-send-email-laura@labbott.name>


Each of the different allocators (SLAB/SLUB/SLOB) handles
clearing of objects differently depending on configuration.
Add common infrastructure for selecting sanitization levels
(off, slow path only, partial, full) and marking caches as
appropriate.

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

Signed-off-by: Laura Abbott <laura@labbott.name>
---
 include/linux/slab.h     |  7 +++++++
 include/linux/slab_def.h |  4 ++++
 mm/slab.h                | 22 ++++++++++++++++++++
 mm/slab_common.c         | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 86 insertions(+)

diff --git a/include/linux/slab.h b/include/linux/slab.h
index 2037a86..35c1e2d 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -23,6 +23,13 @@
 #define SLAB_DEBUG_FREE		0x00000100UL	/* DEBUG: Perform (expensive) checks on free */
 #define SLAB_RED_ZONE		0x00000400UL	/* DEBUG: Red zone objs in a cache */
 #define SLAB_POISON		0x00000800UL	/* DEBUG: Poison objects */
+
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+#define SLAB_NO_SANITIZE        0x00001000UL    /* Do not sanitize objs on free */
+#else
+#define SLAB_NO_SANITIZE        0x00000000UL
+#endif
+
 #define SLAB_HWCACHE_ALIGN	0x00002000UL	/* Align objs on cache lines */
 #define SLAB_CACHE_DMA		0x00004000UL	/* Use GFP_DMA memory */
 #define SLAB_STORE_USER		0x00010000UL	/* DEBUG: Store the last owner for bug hunting */
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 33d0490..4c3fb93 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -69,6 +69,10 @@ struct kmem_cache {
 	 */
 	int obj_offset;
 #endif /* CONFIG_DEBUG_SLAB */
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+	atomic_t sanitized;
+	atomic_t not_sanitized;
+#endif
 #ifdef CONFIG_MEMCG_KMEM
 	struct memcg_cache_params memcg_params;
 #endif
diff --git a/mm/slab.h b/mm/slab.h
index 7b60871..b54b636 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -66,6 +66,28 @@ extern struct list_head slab_caches;
 /* The slab cache that manages slab cache information */
 extern struct kmem_cache *kmem_cache;
 
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+#ifdef CONFIG_X86_64
+#define SLAB_MEMORY_SANITIZE_VALUE       '\xfe'
+#else
+#define SLAB_MEMORY_SANITIZE_VALUE       '\xff'
+#endif
+enum slab_sanitize_mode {
+	/* No sanitization */
+	SLAB_SANITIZE_OFF = 0,
+
+	/* Partial sanitization happens only on the slow path */
+	SLAB_SANITIZE_PARTIAL_SLOWPATH = 1,
+
+	/* Partial sanitization happens everywhere */
+	SLAB_SANITIZE_PARTIAL = 2,
+
+	/* Sanitization happens on all slabs, all paths */
+	SLAB_SANITIZE_FULL = 3,
+};
+extern enum slab_sanitize_mode sanitize_slab;
+#endif
+
 unsigned long calculate_alignment(unsigned long flags,
 		unsigned long align, unsigned long size);
 
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 3c6a86b..4b28f70 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -30,6 +30,42 @@ LIST_HEAD(slab_caches);
 DEFINE_MUTEX(slab_mutex);
 struct kmem_cache *kmem_cache;
 
+
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+enum slab_sanitize_mode sanitize_slab = SLAB_SANITIZE_PARTIAL;
+static int __init sanitize_slab_setup(char *str)
+{
+	if (!str)
+		return 0;
+
+	if (!strcmp(str, "0") || !strcmp(str, "off")) {
+		pr_info("slab sanitization disabled");
+		sanitize_slab = SLAB_SANITIZE_OFF;
+	} else if (!strcmp(str, "1") || !strcmp(str, "slow")) {
+		pr_info("slab sanitization partial slow path");
+		sanitize_slab = SLAB_SANITIZE_PARTIAL_SLOWPATH;
+	} else if (!strcmp(str, "2") || !strcmp(str, "partial")) {
+		pr_info("slab sanitization partial");
+		sanitize_slab = SLAB_SANITIZE_PARTIAL;
+	} else if (!strcmp(str, "3") || !strcmp(str, "full")) {
+		pr_info("slab sanitization full");
+		sanitize_slab = SLAB_SANITIZE_FULL;
+	} else
+		pr_err("slab sanitization: unsupported option '%s'\n", str);
+
+	return 0;
+}
+early_param("sanitize_slab", sanitize_slab_setup);
+
+static inline bool sanitize_mergeable(unsigned long flags)
+{
+	return (sanitize_slab == SLAB_SANITIZE_OFF) || (flags & SLAB_NO_SANITIZE);
+}
+#else
+static inline bool sanitize_mergeable(unsigned long flags) { return true; }
+#endif
+
+
 /*
  * Set of flags that will prevent slab merging
  */
@@ -227,6 +263,9 @@ static inline void destroy_memcg_params(struct kmem_cache *s)
  */
 int slab_unmergeable(struct kmem_cache *s)
 {
+	if (!sanitize_mergeable(s->flags))
+		return 1;
+
 	if (slab_nomerge || (s->flags & SLAB_NEVER_MERGE))
 		return 1;
 
@@ -250,6 +289,9 @@ struct kmem_cache *find_mergeable(size_t size, size_t align,
 {
 	struct kmem_cache *s;
 
+	if (!sanitize_mergeable(flags))
+		return NULL;
+
 	if (slab_nomerge || (flags & SLAB_NEVER_MERGE))
 		return NULL;
 
@@ -407,6 +449,13 @@ kmem_cache_create(const char *name, size_t size, size_t align,
 	 */
 	flags &= CACHE_CREATE_MASK;
 
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+	if (sanitize_slab == SLAB_SANITIZE_OFF || (flags & SLAB_DESTROY_BY_RCU))
+		flags |= SLAB_NO_SANITIZE;
+	else if (sanitize_slab == SLAB_SANITIZE_FULL)
+		flags &= ~SLAB_NO_SANITIZE;
+#endif
+
 	s = __kmem_cache_alias(name, size, align, flags, ctor);
 	if (s)
 		goto out_unlock;
@@ -1050,6 +1099,10 @@ static void print_slabinfo_header(struct seq_file *m)
 		 "<error> <maxfreeable> <nodeallocs> <remotefrees> <alienoverflow>");
 	seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>");
 #endif
+#ifdef CONFIG_SLAB_MEMORY_SANITIZE
+	seq_puts(m, " : sanitization <sanitized> <not_sanitized>");
+#endif
+
 	seq_putc(m, '\n');
 }
 
-- 
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>

  reply	other threads:[~2015-12-22  3:40 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 ` Laura Abbott [this message]
2015-12-22 20:48   ` [RFC][PATCH 1/7] mm/slab_common.c: Add common support for slab saniziation 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 ` [RFC][PATCH 2/7] slub: Add support for sanitization Laura Abbott
2015-12-22  3:40 ` [RFC][PATCH 3/7] slab: " 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-2-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).