linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: "Larry H." <research@subreption.com>
To: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Ingo Molnar <mingo@elte.hu>, Rik van Riel <riel@redhat.com>,
	linux-kernel@vger.kernel.org, Linus Torvalds <torvalds@osdl.org>,
	linux-mm@kvack.org, Ingo Molnar <mingo@redhat.com>,
	pageexec@freemail.hu
Subject: [PATCH] Support for kernel memory sanitization
Date: Fri, 22 May 2009 16:25:26 -0700	[thread overview]
Message-ID: <20090522232526.GG13971@oblivion.subreption.com> (raw)
In-Reply-To: <20090522192158.28fe412e@lxorguk.ukuu.org.uk>

[PATCH] Support for kernel memory sanitization

This patch adds support for the CONFIDENTIAL flag to the SLAB and SLUB
allocators. An additional GFP flag is added for use with higher level
allocators (GFP_CONFIDENTIAL, which implies GFP_ZERO).

A boot command line option (sanitize_mem) is added for the page
allocator to perform sanitization of all pages upon release and
allocation.

The code is largely based off the memory sanitization feature in the
PaX project (licensed under the GPL v2 terms) and the original
PG_sensitive patch which allowed fine-grained marking of pages using
a page flag. The lack of a page flag makes the gfp flag mostly useless,
since we can't track pages with the sensitive/confidential bit, and
properly sanitize them on release. The only way to overcome this
limitation is to enable the sanitize_mem boot option and perform
unconditional page sanitization.

This avoids leaking sensitive information when memory is released to
the system after use, for example in cryptographic subsystems. More
specifically, the following threats are addressed:

	1. Information leaks in use-after-free or uninitialized
	variable usage scenarios, such as CVE-2005-0400,
	CVE-2009-0787 and CVE-2007-6417.

	2. Data remanence based attacks, such as Iceman/Coldboot,
	which combine cold rebooting and memory image scanning
	to extract cryptographic secrets (ex. detecting AES key
	expansion blocks, RSA key patterns, etc) or other
	confidential information.

	3. Re-allocation based information leaks, especially in the
	SLAB/SLUB allocators which use LIFO caches and might expose
	sensitive data out of context (when a caller allocates an
	object and receives a pointer to a location which was used
	previously by another user).

The "Shredding Your Garbage: Reducing Data Lifetime Through Secure
Deallocation" paper by Jim Chow et. al from the Stanford University
Department of Computer Science, explains the security implications of
insecure deallocation, and provides extensive information with figures
and applications thoroughly analyzed for this behavior [1]. More recently
this issue came to widespread attention when the "Lest We Remember:
Cold Boot Attacks on Encryption Keys" (by Halderman et. al) paper was
published [2].

This patch has been tested on x86 and amd64, with and without HIGHMEM.

	[1] http://www.stanford.edu/~blp/papers/shredding.html
	[2] http://citp.princeton.edu/memory/
	[3] http://marc.info/?l=linux-mm&m=124284428226461&w=2
	[4] http://marc.info/?t=124284431000002&r=1&w=2

Signed-off-by: Larry H. <research@subreption.com>

---
 Documentation/kernel-parameters.txt    |    2 ++
 arch/alpha/include/asm/kmap_types.h    |    3 ++-
 arch/arm/include/asm/kmap_types.h      |    1 +
 arch/avr32/include/asm/kmap_types.h    |    3 ++-
 arch/blackfin/include/asm/kmap_types.h |    1 +
 arch/cris/include/asm/kmap_types.h     |    1 +
 arch/h8300/include/asm/kmap_types.h    |    1 +
 arch/ia64/include/asm/kmap_types.h     |    3 ++-
 arch/m68k/include/asm/kmap_types_mm.h  |    1 +
 arch/m68k/include/asm/kmap_types_no.h  |    1 +
 arch/mips/include/asm/kmap_types.h     |    3 ++-
 arch/parisc/include/asm/kmap_types.h   |    3 ++-
 arch/powerpc/include/asm/kmap_types.h  |    1 +
 arch/s390/include/asm/kmap_types.h     |    1 +
 arch/sh/include/asm/kmap_types.h       |    3 ++-
 arch/sparc/include/asm/kmap_types.h    |    1 +
 arch/um/include/asm/kmap_types.h       |    1 +
 arch/x86/include/asm/kmap_types.h      |    3 ++-
 arch/xtensa/include/asm/kmap_types.h   |    1 +
 include/asm-frv/kmap_types.h           |    1 +
 include/asm-m32r/kmap_types.h          |    3 ++-
 include/asm-mn10300/kmap_types.h       |    1 +
 include/linux/gfp.h                    |    2 ++
 include/linux/highmem.h                |   12 ++++++++++++
 include/linux/mm.h                     |    2 ++
 include/linux/slab.h                   |    1 +
 mm/page_alloc.c                        |   30 +++++++++++++++++++++++++++++-
 mm/slab.c                              |   13 +++++++++++--
 mm/slub.c                              |   24 ++++++++++++++++++++++++
 29 files changed, 112 insertions(+), 11 deletions(-)

Index: linux-2.6/Documentation/kernel-parameters.txt
===================================================================
--- linux-2.6.orig/Documentation/kernel-parameters.txt
+++ linux-2.6/Documentation/kernel-parameters.txt
@@ -2494,6 +2494,8 @@ and is between 256 and 4096 characters. 
 	norandmaps	Don't use address space randomization.  Equivalent to
 			echo 0 > /proc/sys/kernel/randomize_va_space
 
+	sanitize_mem	Enables sanitization of all allocated pages.
+
 ______________________________________________________________________
 
 TODO:
Index: linux-2.6/arch/alpha/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/alpha/include/asm/kmap_types.h
+++ linux-2.6/arch/alpha/include/asm/kmap_types.h
@@ -24,7 +24,8 @@ D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
 D(11)	KM_SOFTIRQ0,
 D(12)	KM_SOFTIRQ1,
-D(13)	KM_TYPE_NR
+D(13)  KM_CLEARPAGE,
+D(14)  KM_TYPE_NR
 };
 
 #undef D
Index: linux-2.6/arch/arm/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/arm/include/asm/kmap_types.h
+++ linux-2.6/arch/arm/include/asm/kmap_types.h
@@ -18,6 +18,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/avr32/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/avr32/include/asm/kmap_types.h
+++ linux-2.6/arch/avr32/include/asm/kmap_types.h
@@ -22,7 +22,8 @@ D(10)	KM_IRQ0,
 D(11)	KM_IRQ1,
 D(12)	KM_SOFTIRQ0,
 D(13)	KM_SOFTIRQ1,
-D(14)	KM_TYPE_NR
+D(14)	KM_CLEARPAGE,
+D(15)	KM_TYPE_NR
 };
 
 #undef D
Index: linux-2.6/arch/blackfin/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/blackfin/include/asm/kmap_types.h
+++ linux-2.6/arch/blackfin/include/asm/kmap_types.h
@@ -15,6 +15,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/cris/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/cris/include/asm/kmap_types.h
+++ linux-2.6/arch/cris/include/asm/kmap_types.h
@@ -19,6 +19,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/h8300/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/h8300/include/asm/kmap_types.h
+++ linux-2.6/arch/h8300/include/asm/kmap_types.h
@@ -15,6 +15,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/ia64/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/ia64/include/asm/kmap_types.h
+++ linux-2.6/arch/ia64/include/asm/kmap_types.h
@@ -22,7 +22,8 @@ D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
 D(11)	KM_SOFTIRQ0,
 D(12)	KM_SOFTIRQ1,
-D(13)	KM_TYPE_NR
+D(13)	KM_CLEARPAGE,
+D(14)	KM_TYPE_NR
 };
 
 #undef D
Index: linux-2.6/arch/m68k/include/asm/kmap_types_mm.h
===================================================================
--- linux-2.6.orig/arch/m68k/include/asm/kmap_types_mm.h
+++ linux-2.6/arch/m68k/include/asm/kmap_types_mm.h
@@ -15,6 +15,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/m68k/include/asm/kmap_types_no.h
===================================================================
--- linux-2.6.orig/arch/m68k/include/asm/kmap_types_no.h
+++ linux-2.6/arch/m68k/include/asm/kmap_types_no.h
@@ -15,6 +15,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/mips/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/mips/include/asm/kmap_types.h
+++ linux-2.6/arch/mips/include/asm/kmap_types.h
@@ -22,7 +22,8 @@ D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
 D(11)	KM_SOFTIRQ0,
 D(12)	KM_SOFTIRQ1,
-D(13)	KM_TYPE_NR
+D(13)	KM_CLEARPAGE,
+D(14)	KM_TYPE_NR
 };
 
 #undef D
Index: linux-2.6/arch/parisc/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/parisc/include/asm/kmap_types.h
+++ linux-2.6/arch/parisc/include/asm/kmap_types.h
@@ -22,7 +22,8 @@ D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
 D(11)	KM_SOFTIRQ0,
 D(12)	KM_SOFTIRQ1,
-D(13)	KM_TYPE_NR
+D(13)	KM_CLEARPAGE,
+D(14)	KM_TYPE_NR
 };
 
 #undef D
Index: linux-2.6/arch/powerpc/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/powerpc/include/asm/kmap_types.h
+++ linux-2.6/arch/powerpc/include/asm/kmap_types.h
@@ -26,6 +26,7 @@ enum km_type {
 	KM_SOFTIRQ1,
 	KM_PPC_SYNC_PAGE,
 	KM_PPC_SYNC_ICACHE,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/s390/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/s390/include/asm/kmap_types.h
+++ linux-2.6/arch/s390/include/asm/kmap_types.h
@@ -16,6 +16,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,	
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/sh/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/sh/include/asm/kmap_types.h
+++ linux-2.6/arch/sh/include/asm/kmap_types.h
@@ -24,7 +24,8 @@ D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
 D(11)	KM_SOFTIRQ0,
 D(12)	KM_SOFTIRQ1,
-D(13)	KM_TYPE_NR
+D(13)	KM_CLEARPAGE,
+D(14)	KM_TYPE_NR
 };
 
 #undef D
Index: linux-2.6/arch/sparc/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/sparc/include/asm/kmap_types.h
+++ linux-2.6/arch/sparc/include/asm/kmap_types.h
@@ -19,6 +19,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/um/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/um/include/asm/kmap_types.h
+++ linux-2.6/arch/um/include/asm/kmap_types.h
@@ -23,6 +23,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/arch/x86/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/kmap_types.h
+++ linux-2.6/arch/x86/include/asm/kmap_types.h
@@ -21,7 +21,8 @@ D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
 D(11)	KM_SOFTIRQ0,
 D(12)	KM_SOFTIRQ1,
-D(13)	KM_TYPE_NR
+D(13)	KM_CLEARPAGE,
+D(14)	KM_TYPE_NR
 };
 
 #undef D
Index: linux-2.6/arch/xtensa/include/asm/kmap_types.h
===================================================================
--- linux-2.6.orig/arch/xtensa/include/asm/kmap_types.h
+++ linux-2.6/arch/xtensa/include/asm/kmap_types.h
@@ -25,6 +25,7 @@ enum km_type {
   KM_IRQ1,
   KM_SOFTIRQ0,
   KM_SOFTIRQ1,
+  KM_CLEARPAGE,
   KM_TYPE_NR
 };
 
Index: linux-2.6/include/asm-frv/kmap_types.h
===================================================================
--- linux-2.6.orig/include/asm-frv/kmap_types.h
+++ linux-2.6/include/asm-frv/kmap_types.h
@@ -23,6 +23,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/include/asm-m32r/kmap_types.h
===================================================================
--- linux-2.6.orig/include/asm-m32r/kmap_types.h
+++ linux-2.6/include/asm-m32r/kmap_types.h
@@ -21,7 +21,8 @@ D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
 D(11)	KM_SOFTIRQ0,
 D(12)	KM_SOFTIRQ1,
-D(13)	KM_TYPE_NR
+D(13)	KM_CLEARPAGE,
+D(14)	KM_TYPE_NR
 };
 
 #undef D
Index: linux-2.6/include/asm-mn10300/kmap_types.h
===================================================================
--- linux-2.6.orig/include/asm-mn10300/kmap_types.h
+++ linux-2.6/include/asm-mn10300/kmap_types.h
@@ -25,6 +25,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_CLEARPAGE,
 	KM_TYPE_NR
 };
 
Index: linux-2.6/include/linux/gfp.h
===================================================================
--- linux-2.6.orig/include/linux/gfp.h
+++ linux-2.6/include/linux/gfp.h
@@ -50,6 +50,7 @@ struct vm_area_struct;
 #define __GFP_THISNODE	((__force gfp_t)0x40000u)/* No fallback, no policies */
 #define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) /* Page is reclaimable */
 #define __GFP_MOVABLE	((__force gfp_t)0x100000u)  /* Page is movable */
+#define __GFP_CONFIDENTIAL	((__force gfp_t)0x200000u)  /* Page contains sensitive information */
 
 #define __GFP_BITS_SHIFT 21	/* Room for 21 __GFP_FOO bits */
 #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
@@ -69,6 +70,7 @@ struct vm_area_struct;
 #define GFP_HIGHUSER_MOVABLE	(__GFP_WAIT | __GFP_IO | __GFP_FS | \
 				 __GFP_HARDWALL | __GFP_HIGHMEM | \
 				 __GFP_MOVABLE)
+#define GFP_CONFIDENTIAL	(__GFP_CONFIDENTIAL | __GFP_ZERO)
 
 #ifdef CONFIG_NUMA
 #define GFP_THISNODE	(__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
Index: linux-2.6/include/linux/highmem.h
===================================================================
--- linux-2.6.orig/include/linux/highmem.h
+++ linux-2.6/include/linux/highmem.h
@@ -124,6 +124,18 @@ static inline void clear_highpage(struct
 	kunmap_atomic(kaddr, KM_USER0);
 }
 
+static inline void sanitize_highpage(struct page *page)
+{
+	void *kaddr;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	kaddr = kmap_atomic(page, KM_CLEARPAGE);
+	clear_page(kaddr);
+	kunmap_atomic(kaddr, KM_CLEARPAGE);
+	local_irq_restore(flags);
+}
+
 static inline void zero_user_segments(struct page *page,
 	unsigned start1, unsigned end1,
 	unsigned start2, unsigned end2)
Index: linux-2.6/include/linux/mm.h
===================================================================
--- linux-2.6.orig/include/linux/mm.h
+++ linux-2.6/include/linux/mm.h
@@ -25,6 +25,7 @@ extern unsigned long max_mapnr;
 #endif
 
 extern unsigned long num_physpages;
+extern int sanitize_all_mem;
 extern void * high_memory;
 extern int page_cluster;
 
@@ -104,6 +105,7 @@ extern unsigned int kobjsize(const void 
 #define VM_CAN_NONLINEAR 0x08000000	/* Has ->fault & does nonlinear pages */
 #define VM_MIXEDMAP	0x10000000	/* Can contain "struct page" and pure PFN pages */
 #define VM_SAO		0x20000000	/* Strong Access Ordering (powerpc) */
+#define VM_CONFIDENTIAL	0x40000000	/* Will contain sensitive data */
 
 #ifndef VM_STACK_DEFAULT_FLAGS		/* arch can override this */
 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
Index: linux-2.6/include/linux/slab.h
===================================================================
--- linux-2.6.orig/include/linux/slab.h
+++ linux-2.6/include/linux/slab.h
@@ -23,6 +23,7 @@
 #define SLAB_CACHE_DMA		0x00004000UL	/* Use GFP_DMA memory */
 #define SLAB_STORE_USER		0x00010000UL	/* DEBUG: Store the last owner for bug hunting */
 #define SLAB_PANIC		0x00040000UL	/* Panic if kmem_cache_create() fails */
+#define SLAB_CONFIDENTIAL		0x00080000UL	/* Memory will hold sensitive information */
 /*
  * SLAB_DESTROY_BY_RCU - **WARNING** READ THIS!
  *
Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c
+++ linux-2.6/mm/page_alloc.c
@@ -123,6 +123,7 @@ int min_free_kbytes = 1024;
 unsigned long __meminitdata nr_kernel_pages;
 unsigned long __meminitdata nr_all_pages;
 static unsigned long __meminitdata dma_reserve;
+int sanitize_all_mem;
 
 #ifdef CONFIG_ARCH_POPULATES_NODE_MAP
   /*
@@ -221,6 +222,17 @@ static inline int bad_range(struct zone 
 }
 #endif
 
+static __init int setup_page_sanitization(char *s)
+{
+	if (s) {
+		sanitize_all_mem = 1;
+		return 1;
+	}
+
+	return 0;
+}
+early_param("sanitize_mem", setup_page_sanitization);
+
 static void bad_page(struct page *page)
 {
 	static unsigned long resume;
@@ -545,6 +557,7 @@ static void free_one_page(struct zone *z
 
 static void __free_pages_ok(struct page *page, unsigned int order)
 {
+	unsigned long index = 1UL << order;
 	unsigned long flags;
 	int i;
 	int bad = 0;
@@ -559,6 +572,16 @@ static void __free_pages_ok(struct page 
 		debug_check_no_obj_freed(page_address(page),
 					   PAGE_SIZE << order);
 	}
+
+	/*
+	 * Page sanitization is enabled, let's clear the page contents before
+	 * release.
+	 */
+	if (sanitize_all_mem) {
+		for (; index; --index)
+			sanitize_highpage(page + index - 1);
+	}
+
 	arch_free_page(page, order);
 	kernel_map_pages(page, 1 << order, 0);
 
@@ -647,7 +670,8 @@ static int prep_new_page(struct page *pa
 	arch_alloc_page(page, order);
 	kernel_map_pages(page, 1 << order, 1);
 
-	if (gfp_flags & __GFP_ZERO)
+	if (((gfp_flags & __GFP_ZERO) || (gfp_flags & __GFP_CONFIDENTIAL))
+		|| sanitize_all_mem)
 		prep_zero_page(page, order, gfp_flags);
 
 	if (order && (gfp_flags & __GFP_COMP))
@@ -1009,6 +1033,10 @@ static void free_hot_cold_page(struct pa
 		debug_check_no_locks_freed(page_address(page), PAGE_SIZE);
 		debug_check_no_obj_freed(page_address(page), PAGE_SIZE);
 	}
+
+	if (sanitize_all_mem)
+		sanitize_highpage(page);
+
 	arch_free_page(page, 0);
 	kernel_map_pages(page, 1, 0);
 
Index: linux-2.6/mm/slab.c
===================================================================
--- linux-2.6.orig/mm/slab.c
+++ linux-2.6/mm/slab.c
@@ -2270,7 +2270,11 @@ kmem_cache_create (const char *name, siz
 	align = ralign;
 
 	/* Get cache's description obj. */
-	cachep = kmem_cache_zalloc(&cache_cache, GFP_KERNEL);
+	if (flags & SLAB_CONFIDENTIAL)
+		cachep = kmem_cache_zalloc(&cache_cache, GFP_KERNEL | GFP_CONFIDENTIAL);
+	else
+		cachep = kmem_cache_zalloc(&cache_cache, GFP_KERNEL);
+
 	if (!cachep)
 		goto oops;
 
@@ -2356,6 +2360,8 @@ kmem_cache_create (const char *name, siz
 	cachep->gfpflags = 0;
 	if (CONFIG_ZONE_DMA_FLAG && (flags & SLAB_CACHE_DMA))
 		cachep->gfpflags |= GFP_DMA;
+	if (flags & SLAB_CONFIDENTIAL)
+		cachep->gfpflags |= GFP_CONFIDENTIAL;
 	cachep->buffer_size = size;
 	cachep->reciprocal_buffer_size = reciprocal_value(size);
 
@@ -3350,7 +3356,7 @@ __cache_alloc_node(struct kmem_cache *ca
 	local_irq_restore(save_flags);
 	ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
 
-	if (unlikely((flags & __GFP_ZERO) && ptr))
+	if (unlikely(((flags & __GFP_ZERO) || (flags && __GFP_CONFIDENTIAL)) && ptr))
 		memset(ptr, 0, obj_size(cachep));
 
 	return ptr;
@@ -3519,6 +3525,9 @@ static inline void __cache_free(struct k
 	check_irq_off();
 	objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
 
+	if (unlikely(cachep->flags & SLAB_CONFIDENTIAL))
+		memset(objp, 0, obj_size(cachep));
+
 	/*
 	 * Skip calling cache_free_alien() when the platform is not numa.
 	 * This will avoid cache misses that happen while accessing slabp (which
Index: linux-2.6/mm/slub.c
===================================================================
--- linux-2.6.orig/mm/slub.c
+++ linux-2.6/mm/slub.c
@@ -1135,6 +1135,9 @@ static struct page *new_slab(struct kmem
 
 	start = page_address(page);
 
+	if (unlikely(s->flags & SLAB_CONFIDENTIAL))
+		memset(start, 0, PAGE_SIZE << compound_order(page));
+
 	if (unlikely(s->flags & SLAB_POISON))
 		memset(start, POISON_INUSE, PAGE_SIZE << compound_order(page));
 
@@ -1646,6 +1649,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
 static void __slab_free(struct kmem_cache *s, struct page *page,
 			void *x, unsigned long addr, unsigned int offset)
 {
+	int objsize;
 	void *prior;
 	void **object = (void *)x;
 	struct kmem_cache_cpu *c;
@@ -1662,6 +1666,23 @@ checks_ok:
 	page->freelist = object;
 	page->inuse--;
 
+	if (s->flags & SLAB_CONFIDENTIAL) {
+		/* Size calculation based off ksize() */
+		objsize = s->size;
+
+		if (unlikely(!PageSlab(page))) {
+			WARN_ON(!PageCompound(page));
+			objsize = PAGE_SIZE << compound_order(page);
+		} else {
+			if (s->flags & (SLAB_RED_ZONE | SLAB_POISON))
+				objsize = s->objsize;
+			else if (s->flags & (SLAB_DESTROY_BY_RCU | SLAB_STORE_USER))
+				objsize = s->inuse;
+		}
+
+		memset(x, 0, objsize);
+	}
+
 	if (unlikely(PageSlubFrozen(page))) {
 		stat(c, FREE_FROZEN);
 		goto out_unlock;
@@ -2292,6 +2313,9 @@ static int calculate_sizes(struct kmem_c
 	if (s->flags & SLAB_RECLAIM_ACCOUNT)
 		s->allocflags |= __GFP_RECLAIMABLE;
 
+	if (s->flags & SLAB_CONFIDENTIAL)
+		s->allocflags |= GFP_CONFIDENTIAL;
+
 	/*
 	 * Determine the number of objects per slab
 	 */

--
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:[~2009-05-22 23:25 UTC|newest]

Thread overview: 114+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-20 18:30 [patch 0/5] Support for sanitization flag in low-level page allocator Larry H.
2009-05-20 20:42 ` Peter Zijlstra
2009-05-20 21:24   ` Larry H.
2009-05-21 15:21     ` Robin Holt
2009-05-21 18:43       ` Larry H.
2009-05-29 22:58     ` Andrew Morton
2009-05-30  7:00       ` Larry H.
2009-05-30  7:12       ` Pekka Enberg
2009-05-30  7:35         ` Larry H.
2009-05-30  7:39           ` Pekka Enberg
2009-05-21 19:08   ` Rik van Riel
2009-05-21 19:26     ` Alan Cox
2009-05-21 19:56       ` Larry H.
2009-05-21 20:47         ` Alan Cox
2009-05-21 21:46           ` Larry H.
2009-05-21 22:47             ` Alan Cox
2009-05-22 11:22               ` Larry H.
2009-05-22 13:37                 ` Alan Cox
2009-05-26 19:02       ` Pavel Machek
2009-05-21 19:17 ` Rik van Riel
2009-05-21 19:30   ` Larry H.
2009-05-22  7:34   ` Ingo Molnar
2009-05-22 11:38     ` Larry H.
2009-05-22 13:39       ` Alan Cox
2009-05-22 18:03         ` Larry H.
2009-05-22 18:21           ` Alan Cox
2009-05-22 23:25             ` Larry H. [this message]
2009-05-22 23:52               ` [PATCH] Support for kernel memory sanitization Randy Dunlap
2009-05-22 23:40             ` [patch 0/5] Support for sanitization flag in low-level page allocator Larry H.
2009-05-23  8:09               ` Alan Cox
2009-05-23 15:56                 ` Arjan van de Ven
2009-05-23 18:21                   ` [PATCH] Support for unconditional page sanitization Larry H.
2009-05-23 21:05                     ` Arjan van de Ven
2009-05-24 10:19                       ` pageexec
2009-05-24 16:38                         ` Arjan van de Ven
2009-05-28 19:36                   ` [patch 0/5] Support for sanitization flag in low-level page allocator Peter Zijlstra
2009-05-29 14:32                     ` Arjan van de Ven
2009-05-30  5:48                       ` Larry H.
2009-05-30 10:39                         ` Peter Zijlstra
2009-05-30 10:43                           ` Larry H.
2009-05-30 11:42                           ` pageexec
2009-05-30 13:21                             ` Peter Zijlstra
2009-05-30 13:24                               ` Peter Zijlstra
2009-05-30 13:54                               ` pageexec
2009-05-30 14:04                                 ` Larry H.
2009-05-30 14:13                                 ` Rik van Riel
2009-05-30 14:08                               ` Rik van Riel
2009-05-30 14:30                               ` Alan Cox
2009-05-30 14:45                                 ` Peter Zijlstra
2009-05-30 14:48                                   ` Rik van Riel
2009-05-30 17:00                                     ` Larry H.
2009-05-30 17:25                                       ` Larry H.
2009-05-30 18:32                                         ` Ingo Molnar
2009-06-05 13:15                                   ` Pavel Machek
2009-05-31 14:38                           ` Arjan van de Ven
2009-05-31 15:03                             ` Arjan van de Ven
2009-05-22 18:37           ` Nai Xia
2009-05-22 19:18           ` Nai Xia
2009-05-23 12:49       ` Ingo Molnar
2009-05-23 22:28         ` Larry H.
2009-05-23 22:42         ` Rik van Riel
2009-05-25  1:17           ` [PATCH] Sanitize memory on kfree() and kmem_cache_free() Larry H.
2009-05-27 22:34           ` [patch 0/5] Support for sanitization flag in low-level page allocator Ingo Molnar
2009-05-28  6:27             ` Alan Cox
2009-05-28  7:00               ` Larry H.
2009-05-28  9:08               ` Ingo Molnar
2009-05-28 11:50                 ` Alan Cox
2009-05-28 19:44                   ` Peter Zijlstra
2009-05-30  7:35                   ` Pekka Enberg
2009-05-30  7:50                     ` Larry H.
2009-05-30  7:53                       ` Pekka Enberg
2009-05-30  8:20                         ` Larry H.
2009-05-30  8:33                           ` Pekka Enberg
2009-05-30 15:05                           ` Ray Lee
2009-05-30 17:34                           ` Ingo Molnar
2009-05-30 18:03                             ` Larry H.
2009-05-30 18:21                               ` Ingo Molnar
2009-05-30 18:45                                 ` Larry H.
2009-05-30 19:08                                   ` Ingo Molnar
2009-05-30 20:39                                     ` Rik van Riel
2009-05-30 20:53                                       ` Pekka Enberg
2009-05-30 21:33                                         ` Larry H.
2009-05-30 23:13                                           ` Alan Cox
2009-05-30 23:18                                             ` Larry H.
2009-05-31  6:30                                               ` Pekka Enberg
2009-05-31 11:49                                                 ` Larry H.
2009-05-31  7:17                                           ` Pekka Enberg
2009-05-31 11:58                                             ` Larry H.
2009-05-31 12:16                                               ` Pekka Enberg
2009-05-31 12:30                                                 ` Larry H.
2009-05-31 12:35                                                   ` Pekka Enberg
2009-05-30 23:10                                         ` Alan Cox
2009-05-31  6:14                                           ` Pekka Enberg
2009-05-31 10:24                                             ` Alan Cox
2009-05-31 10:24                                               ` Pekka Enberg
2009-05-31 12:16                                             ` Larry H.
2009-05-31 12:19                                               ` Pekka Enberg
2009-05-31 16:25                                               ` Alan Cox
2009-05-30 22:10                                       ` Ingo Molnar
2009-05-30 23:15                                         ` Alan Cox
2009-05-30 20:22                               ` Pekka Enberg
2009-05-30 22:14                                 ` Ingo Molnar
2009-05-30 17:39                         ` Ingo Molnar
2009-05-30  7:57                       ` Pekka Enberg
2009-05-30  9:05                         ` Larry H.
2009-05-30 17:46                           ` Ingo Molnar
2009-05-30 18:09                             ` Larry H.
2009-05-30  8:31                     ` Alan Cox
2009-05-30  8:35                       ` Pekka Enberg
2009-05-30  9:27                         ` Larry H.
2009-05-28 18:48                 ` pageexec
2009-05-30 17:50                   ` Ingo Molnar
2009-05-28 12:48 ` Pavel Machek
2009-05-28 12:55   ` Larry H.

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=20090522232526.GG13971@oblivion.subreption.com \
    --to=research@subreption.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mingo@elte.hu \
    --cc=mingo@redhat.com \
    --cc=pageexec@freemail.hu \
    --cc=riel@redhat.com \
    --cc=torvalds@osdl.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