Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1296518 > unrolled thread

[RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX

Started byLaura Abbott <laura@labbott.name>
First post2015-12-22 04:50 +0100
Last post2015-12-22 21:10 +0100
Articles 8 on this page of 28 — 6 participants

Back to article view | Back to linux.kernel


Contents

  [RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX Laura Abbott <laura@labbott.name> - 2015-12-22 04:50 +0100
    [RFC][PATCH 6/7] mm: Add Kconfig option for slab sanitization Laura Abbott <laura@labbott.name> - 2015-12-22 04:50 +0100
      Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Mathias Krause <minipli@googlemail.com> - 2015-12-22 10:40 +0100
        Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Laura Abbott <laura@labbott.name> - 2015-12-22 19:00 +0100
          Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Mathias Krause <minipli@googlemail.com> - 2015-12-22 19:40 +0100
            Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Laura Abbott <laura@labbott.name> - 2015-12-22 20:20 +0100
            Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Christoph Lameter <cl@linux.com> - 2015-12-22 21:10 +0100
              Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Mathias Krause <minipli@googlemail.com> - 2015-12-22 21:10 +0100
      Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Dave Hansen <dave.hansen@intel.com> - 2015-12-22 16:00 +0100
        Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Christoph Lameter <cl@linux.com> - 2015-12-22 17:30 +0100
          Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Dave Hansen <dave.hansen@intel.com> - 2015-12-22 18:30 +0100
            Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Christoph Lameter <cl@linux.com> - 2015-12-22 19:10 +0100
              Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Dave Hansen <dave.hansen@intel.com> - 2015-12-22 19:20 +0100
                Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Laura Abbott <laura@labbott.name> - 2015-12-22 20:20 +0100
                  Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Dave Hansen <dave.hansen@intel.com> - 2015-12-22 20:40 +0100
          Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Christoph Lameter <cl@linux.com> - 2015-12-22 18:30 +0100
          Re: [kernel-hardening] [RFC][PATCH 6/7] mm: Add Kconfig option for  slab sanitization Dave Hansen <dave.hansen@intel.com> - 2015-12-22 18:30 +0100
    [RFC][PATCH 4/7] slob: Add support for sanitization Laura Abbott <laura@labbott.name> - 2015-12-22 04:50 +0100
    [RFC][PATCH 3/7] slab: Add support for sanitization Laura Abbott <laura@labbott.name> - 2015-12-22 04:50 +0100
    [RFC][PATCH 7/7] lkdtm: Add READ_AFTER_FREE test Laura Abbott <laura@labbott.name> - 2015-12-22 04:50 +0100
    [RFC][PATCH 5/7] mm: Mark several cases as SLAB_NO_SANITIZE Laura Abbott <laura@labbott.name> - 2015-12-22 04:50 +0100
    [RFC][PATCH 1/7] mm/slab_common.c: Add common support for slab saniziation Laura Abbott <laura@labbott.name> - 2015-12-22 04:50 +0100
      Re: [RFC][PATCH 1/7] mm/slab_common.c: Add common support for slab  saniziation Vlastimil Babka <vbabka@suse.cz> - 2015-12-22 21:50 +0100
    [RFC][PATCH 2/7] slub: Add support for sanitization Laura Abbott <laura@labbott.name> - 2015-12-22 04:50 +0100
    Re: [RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX Christoph Lameter <cl@linux.com> - 2015-12-22 17:10 +0100
      Re: [kernel-hardening] Re: [RFC][PATCH 0/7] Sanitization of slabs  based on grsecurity/PaX Dave Hansen <dave.hansen@intel.com> - 2015-12-22 17:20 +0100
      Re: [kernel-hardening] Re: [RFC][PATCH 0/7] Sanitization of slabs  based on grsecurity/PaX Daniel Micay <danielmicay@gmail.com> - 2015-12-22 17:40 +0100
      Re: [RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX Laura Abbott <laura@labbott.name> - 2015-12-22 21:10 +0100

Page 2 of 2 — ← Prev page 1 [2]


#1296525 — [RFC][PATCH 5/7] mm: Mark several cases as SLAB_NO_SANITIZE

FromLaura Abbott <laura@labbott.name>
Date2015-12-22 04:50 +0100
Subject[RFC][PATCH 5/7] mm: Mark several cases as SLAB_NO_SANITIZE
Message-ID<qIm7w-75a-21@gated-at.bofh.it>
In reply to#1296518
Sanitization is useful for security but comes at the cost of performance
in clearing on free. Mark select caches as SLAB_NO_SANITIZE so
sanitization will not happen under the default configuration. The
kernel may be booted with the proper command line option to allow these
caches to be sanitized.

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

Signed-off-by: Laura Abbott <laura@labbott.name>
---
This is the initial set of excludes that the grsecurity patches had.
More may need to be added/removed as the series is tested.
---
 fs/buffer.c       |  2 +-
 fs/dcache.c       |  2 +-
 kernel/fork.c     |  2 +-
 mm/rmap.c         |  4 ++--
 mm/slab.h         |  2 +-
 net/core/skbuff.c | 16 ++++++++--------
 6 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index 4f4cd95..f19e4ab 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -3417,7 +3417,7 @@ void __init buffer_init(void)
 	bh_cachep = kmem_cache_create("buffer_head",
 			sizeof(struct buffer_head), 0,
 				(SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
-				SLAB_MEM_SPREAD),
+				SLAB_MEM_SPREAD|SLAB_NO_SANITIZE),
 				NULL);
 
 	/*
diff --git a/fs/dcache.c b/fs/dcache.c
index 5c33aeb..470f6be 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -3451,7 +3451,7 @@ void __init vfs_caches_init_early(void)
 void __init vfs_caches_init(void)
 {
 	names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
-			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
+			SLAB_NO_SANITIZE|SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
 
 	dcache_init();
 	inode_init();
diff --git a/kernel/fork.c b/kernel/fork.c
index fce002e..35db9c3 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1868,7 +1868,7 @@ void __init proc_caches_init(void)
 	mm_cachep = kmem_cache_create("mm_struct",
 			sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
 			SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
-	vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC);
+	vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC|SLAB_NO_SANITIZE);
 	mmap_init();
 	nsproxy_cache_init();
 }
diff --git a/mm/rmap.c b/mm/rmap.c
index b577fbb..74296d9 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -428,8 +428,8 @@ static void anon_vma_ctor(void *data)
 void __init anon_vma_init(void)
 {
 	anon_vma_cachep = kmem_cache_create("anon_vma", sizeof(struct anon_vma),
-			0, SLAB_DESTROY_BY_RCU|SLAB_PANIC, anon_vma_ctor);
-	anon_vma_chain_cachep = KMEM_CACHE(anon_vma_chain, SLAB_PANIC);
+		0, SLAB_DESTROY_BY_RCU|SLAB_PANIC|SLAB_NO_SANITIZE, anon_vma_ctor);
+	anon_vma_chain_cachep = KMEM_CACHE(anon_vma_chain, SLAB_PANIC|SLAB_NO_SANITIZE);
 }
 
 /*
diff --git a/mm/slab.h b/mm/slab.h
index b54b636..6de99da 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -137,7 +137,7 @@ static inline unsigned long kmem_cache_flags(unsigned long object_size,
 
 /* Legal flag mask for kmem_cache_create(), for various configurations */
 #define SLAB_CORE_FLAGS (SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA | SLAB_PANIC | \
-			 SLAB_DESTROY_BY_RCU | SLAB_DEBUG_OBJECTS )
+			 SLAB_DESTROY_BY_RCU | SLAB_DEBUG_OBJECTS | SLAB_NO_SANITIZE)
 
 #if defined(CONFIG_DEBUG_SLAB)
 #define SLAB_DEBUG_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index b2df375..1d499ea 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3316,15 +3316,15 @@ done:
 void __init skb_init(void)
 {
 	skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
-					      sizeof(struct sk_buff),
-					      0,
-					      SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-					      NULL);
+				sizeof(struct sk_buff),
+				0,
+				SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NO_SANITIZE,
+				NULL);
 	skbuff_fclone_cache = kmem_cache_create("skbuff_fclone_cache",
-						sizeof(struct sk_buff_fclones),
-						0,
-						SLAB_HWCACHE_ALIGN|SLAB_PANIC,
-						NULL);
+				sizeof(struct sk_buff_fclones),
+				0,
+				SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NO_SANITIZE,
+				NULL);
 }
 
 /**
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1296526 — [RFC][PATCH 1/7] mm/slab_common.c: Add common support for slab saniziation

FromLaura Abbott <laura@labbott.name>
Date2015-12-22 04:50 +0100
Subject[RFC][PATCH 1/7] mm/slab_common.c: Add common support for slab saniziation
Message-ID<qIm7w-75a-23@gated-at.bofh.it>
In reply to#1296518
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 from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1297058 — Re: [RFC][PATCH 1/7] mm/slab_common.c: Add common support for slab saniziation

FromVlastimil Babka <vbabka@suse.cz>
Date2015-12-22 21:50 +0100
SubjectRe: [RFC][PATCH 1/7] mm/slab_common.c: Add common support for slab saniziation
Message-ID<qIC2B-hq-5@gated-at.bofh.it>
In reply to#1296526
On 22.12.2015 4:40, Laura Abbott wrote:
> 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>
>  
> +#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,

Can you explain more about this variant? I wonder who might find it useful
except someone getting a false sense of security, but cheaper.
It sounds like wanting the cake and eat it too :)
I would be surprised if such IMHO half-solution existed in the original
PAX_MEMORY_SANITIZE too?

Or is there something that guarantees that the objects freed on hotpath won't
stay there for long so the danger of leak is low? (And what about
use-after-free?) It depends on further slab activity, no? (I'm not that familiar
with SLUB, but I would expect the hotpath there being similar to SLAB freeing
the object on per-cpu array_cache. But, it seems the PARTIAL_SLOWPATH is not
implemented for SLAB, so there might be some fundamental difference I'm missing.)


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1296527 — [RFC][PATCH 2/7] slub: Add support for sanitization

FromLaura Abbott <laura@labbott.name>
Date2015-12-22 04:50 +0100
Subject[RFC][PATCH 2/7] slub: Add support for sanitization
Message-ID<qIm7v-75a-13@gated-at.bofh.it>
In reply to#1296518
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 from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1296871

FromChristoph Lameter <cl@linux.com>
Date2015-12-22 17:10 +0100
Message-ID<qIxFE-694-23@gated-at.bofh.it>
In reply to#1296518
On Mon, 21 Dec 2015, Laura Abbott wrote:

> The biggest change from PAX_MEMORY_SANTIIZE is that this feature sanitizes
> the SL[AOU]B allocators only. My plan is to work on the buddy allocator
> santization after this series gets picked up. A side effect of this is
> that allocations which go directly to the buddy allocator (i.e. large
> allocations) aren't sanitized. I'd like feedback about whether it's worth
> it to add sanitization on that path directly or just use the page
> allocator sanitization when that comes in.

I am not sure what the point of this patchset is. We have a similar effect
to sanitization already in the allocators through two mechanisms:

1. Slab poisoning
2. Allocation with GFP_ZERO

I do not think we need a third one. You could accomplish your goals much
easier without this code churn by either

1. Improve the existing poisoning mechanism. Ensure that there are no
   gaps. Security sensitive kernel slab caches can then be created with
   the  POISONING flag set. Maybe add a Kconfig flag that enables
   POISONING for each cache? What was the issue when you tried using
   posining for sanitization?

2. Add a mechanism that ensures that GFP_ZERO is set for each allocation.
   That way every object you retrieve is zeroed and thus you have implied
   sanitization. This also can be done in a rather simple way by changing
   the  GFP_KERNEL etc constants to include __GFP_ZERO depending on a
   Kconfig option. Or add some runtime setting of the gfp flags somewhere.

Generally I would favor option #2 if you must have sanitization because
that is the only option to really give you a deterministic content of
object on each allocation. Any half way measures would not work I think.

Note also that most allocations are already either allocations that zero
the content or they are immediately initializing the content of the
allocated object. After all the object is not really usable if the
content is random. You may be able to avoid this whole endeavor by
auditing the kernel for locations where the object is not initialized
after allocation.

Once one recognizes the above it seems that sanitization is pretty
useless. Its just another pass of writing zeroes before the allocator or
uer of the allocated object sets up deterministic content of the object or
-- in most cases -- zeroes it again.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1296880 — Re: [kernel-hardening] Re: [RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX

FromDave Hansen <dave.hansen@intel.com>
Date2015-12-22 17:20 +0100
SubjectRe: [kernel-hardening] Re: [RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX
Message-ID<qIxPk-6cI-11@gated-at.bofh.it>
In reply to#1296871
On 12/22/2015 08:08 AM, Christoph Lameter wrote:
> 2. Add a mechanism that ensures that GFP_ZERO is set for each allocation.
>    That way every object you retrieve is zeroed and thus you have implied
>    sanitization. This also can be done in a rather simple way by changing
>    the  GFP_KERNEL etc constants to include __GFP_ZERO depending on a
>    Kconfig option. Or add some runtime setting of the gfp flags somewhere.

That's a more comprehensive barrier to leaking information than what we
have now, and it would _also_ cover a big chunk of normal
alloc_page()-style allocations which would be nice.

But, doing this on the allocation side is less comprehensive than doing
at free() time.  We (ideally) want to make sure that unallocated memory
at rest does not contain sensitive contents.

Also, the free path _tends_ to be a bit less performance-critical than
the allocation side.  For instance, I think we generally care about
fork() performance a lot more than exit(). :)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1296889 — Re: [kernel-hardening] Re: [RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX

FromDaniel Micay <danielmicay@gmail.com>
Date2015-12-22 17:40 +0100
SubjectRe: [kernel-hardening] Re: [RFC][PATCH 0/7] Sanitization of slabs based on grsecurity/PaX
Message-ID<qIy8G-6kD-29@gated-at.bofh.it>
In reply to#1296871

[Multipart message — attachments visible in raw view] — view raw

> I am not sure what the point of this patchset is. We have a similar
> effect
> to sanitization already in the allocators through two mechanisms:

The rationale was covered earlier. Are you responding to that or did you
not see it?

> 1. Slab poisoning
> 2. Allocation with GFP_ZERO
> 
> I do not think we need a third one. You could accomplish your goals
> much
> easier without this code churn by either
> 
> 1. Improve the existing poisoning mechanism. Ensure that there are no
>    gaps. Security sensitive kernel slab caches can then be created
> with
>    the  POISONING flag set. Maybe add a Kconfig flag that enables
>    POISONING for each cache? What was the issue when you tried using
>    posining for sanitization?
> 
> 2. Add a mechanism that ensures that GFP_ZERO is set for each
> allocation.
>    That way every object you retrieve is zeroed and thus you have
> implied
>    sanitization. This also can be done in a rather simple way by
> changing
>    the  GFP_KERNEL etc constants to include __GFP_ZERO depending on a
>    Kconfig option. Or add some runtime setting of the gfp flags
> somewhere.
> 
> Generally I would favor option #2 if you must have sanitization
> because
> that is the only option to really give you a deterministic content of
> object on each allocation. Any half way measures would not work I
> think.
> 
> Note also that most allocations are already either allocations that
> zero
> the content or they are immediately initializing the content of the
> allocated object. After all the object is not really usable if the
> content is random. You may be able to avoid this whole endeavor by
> auditing the kernel for locations where the object is not initialized
> after allocation.
> 
> Once one recognizes the above it seems that sanitization is pretty
> useless. Its just another pass of writing zeroes before the allocator
> or
> uer of the allocated object sets up deterministic content of the
> object or
> -- in most cases -- zeroes it again.

Sanitization isn't just to prevent leaks from usage of uninitialized
data in later allocations. It's a mitigation for use-after-free (esp. if
it's combined with some form of delayed freeing) and it reduces the
lifetime of data.

[toc] | [prev] | [next] | [standalone]


#1297044

FromLaura Abbott <laura@labbott.name>
Date2015-12-22 21:10 +0100
Message-ID<qIBpV-8vR-27@gated-at.bofh.it>
In reply to#1296871
On 12/22/15 8:08 AM, Christoph Lameter wrote:
> On Mon, 21 Dec 2015, Laura Abbott wrote:
>
>> The biggest change from PAX_MEMORY_SANTIIZE is that this feature sanitizes
>> the SL[AOU]B allocators only. My plan is to work on the buddy allocator
>> santization after this series gets picked up. A side effect of this is
>> that allocations which go directly to the buddy allocator (i.e. large
>> allocations) aren't sanitized. I'd like feedback about whether it's worth
>> it to add sanitization on that path directly or just use the page
>> allocator sanitization when that comes in.
>
> I am not sure what the point of this patchset is. We have a similar effect
> to sanitization already in the allocators through two mechanisms:
>
> 1. Slab poisoning
> 2. Allocation with GFP_ZERO
>
> I do not think we need a third one. You could accomplish your goals much
> easier without this code churn by either
>
> 1. Improve the existing poisoning mechanism. Ensure that there are no
>     gaps. Security sensitive kernel slab caches can then be created with
>     the  POISONING flag set. Maybe add a Kconfig flag that enables
>     POISONING for each cache? What was the issue when you tried using
>     posining for sanitization?

The existing poisoning does work for sanitization but it's still a debug
feature. It seemed more appropriate to keep debug features and non-debug
features separate hence the separate option and configuration.

>
> 2. Add a mechanism that ensures that GFP_ZERO is set for each allocation.
>     That way every object you retrieve is zeroed and thus you have implied
>     sanitization. This also can be done in a rather simple way by changing
>     the  GFP_KERNEL etc constants to include __GFP_ZERO depending on a
>     Kconfig option. Or add some runtime setting of the gfp flags somewhere.
>

That's good for allocation but sanitization is done on free. The goal
is to reduce any leftover data that might be around while on an unallocated
slab.
  
> Generally I would favor option #2 if you must have sanitization because
> that is the only option to really give you a deterministic content of
> object on each allocation. Any half way measures would not work I think.
>
> Note also that most allocations are already either allocations that zero
> the content or they are immediately initializing the content of the
> allocated object. After all the object is not really usable if the
> content is random. You may be able to avoid this whole endeavor by
> auditing the kernel for locations where the object is not initialized
> after allocation.
>
> Once one recognizes the above it seems that sanitization is pretty
> useless. Its just another pass of writing zeroes before the allocator or
> uer of the allocated object sets up deterministic content of the object or
> -- in most cases -- zeroes it again.
>

The sanitization is going towards kernel hardening which is designed to
help keep the kernel secure even when programmers screwed up. Auditing
still won't catch everything. sanitization is going towards the idea
of kernel self-protection which is what Grsecurity is known for
and Kees Cook is trying to promote for mainline
(http://lwn.net/Articles/662219/)

Thanks,
Laura
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | linux.kernel


csiph-web