|
Message-ID: <20170225003232.GA123380@beast> Date: Fri, 24 Feb 2017 16:32:32 -0800 From: Kees Cook <keescook@...omium.org> To: Kaiwan N Billimoria <kaiwan@...wantech.com> Cc: kernel-hardening@...ts.openwall.com Subject: [RFC] mm: enable sanitizing via CONFIG This enables page and slab poisoning by default under CONFIG_MEMORY_SANITIZE. Based on work by Kaiwan N Billimoria. Signed-off-by: Kees Cook <keescook@...omium.org> --- This is more what I had in mind. This is based on the latest patch, but handles slab and slub. I tested slub with lkdtm's READ_AFTER_FREE and READ_BUDDY_AFTER_FREE which both trip the poisoning tests. While doing this, I noticed one major issue with slub/slab poisoning: it performs poisoning both on alloc and free, which is a rather large performance hit, so the next step is likely to find a way to split the poisoning into alloc and free halves so that CONFIG_MEMORY_SANITIZE poisoning will only happen on the free. --- init/main.c | 5 +++++ mm/Kconfig.debug | 23 +++++++++++++++++++++++ mm/page_poison.c | 3 ++- mm/slab.c | 4 ++++ mm/slub.c | 7 +++++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/init/main.c b/init/main.c index 24ea48745061..e5f571bfe56f 100644 --- a/init/main.c +++ b/init/main.c @@ -1030,6 +1030,11 @@ static noinline void __init kernel_init_freeable(void) do_basic_setup(); +#ifdef CONFIG_MEMORY_SANITIZE + pr_debug("[CONFIG_MEMORY_SANITIZE]: page_poisoning_enabled? %s\n", + page_poisoning_enabled() ? "yes" : "no"); +#endif + /* Open the /dev/console on the rootfs, this should never fail */ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) pr_err("Warning: unable to open an initial console.\n"); diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug index afcc550877ff..910a7a359b96 100644 --- a/mm/Kconfig.debug +++ b/mm/Kconfig.debug @@ -90,3 +90,26 @@ config DEBUG_PAGE_REF careful when enabling this feature because it adds about 30 KB to the kernel code. However the runtime performance overhead is virtually nil until the tracepoints are actually enabled. + +config MEMORY_SANITIZE + bool "Enable memory sanitization features" + depends on SLUB || SLAB + select SLUB_DEBUG if SLUB + select PAGE_POISONING + select PAGE_POISONING_NO_SANITY + help + This option enables memory sanitization features. Particularly, + when you turn on this option, it auto-enables: + - page poisoning (without sanity checking) + - kmem_cache poisoning + + Implication: turning this option on will implicitly enable: + - the SLUB_DEBUG switch to the equivalent of the kernel command-line + 'slub_debug=p' (where p=SLAB_POISON). + - page poisoning, equivalent to passing the kernel command-line + option 'page_poison=on'. + + Of course, kernel command-line options 'page_poison' and 'slub_debug' + are still honored. + + If unsure, say N. diff --git a/mm/page_poison.c b/mm/page_poison.c index 2e647c65916b..6f7e37c8ac2f 100644 --- a/mm/page_poison.c +++ b/mm/page_poison.c @@ -7,7 +7,8 @@ #include <linux/ratelimit.h> static bool __page_poisoning_enabled __read_mostly; -static bool want_page_poisoning __read_mostly; +static bool want_page_poisoning __read_mostly = + IS_ENABLED(CONFIG_MEMORY_SANITIZE); static int early_page_poison_param(char *buf) { diff --git a/mm/slab.c b/mm/slab.c index bd63450a9b16..1462b0b8b0a0 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1894,6 +1894,10 @@ unsigned long kmem_cache_flags(unsigned long object_size, unsigned long flags, const char *name, void (*ctor)(void *)) { +#ifdef CONFIG_MEMORY_SANITIZE + flags |= SLAB_POISON; +#endif + return flags; } diff --git a/mm/slub.c b/mm/slub.c index 7f4bc7027ed5..5041f42c942b 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -452,6 +452,8 @@ static inline void *restore_red_left(struct kmem_cache *s, void *p) */ #if defined(CONFIG_SLUB_DEBUG_ON) static int slub_debug = DEBUG_DEFAULT_FLAGS; +#elif defined(CONFIG_MEMORY_SANITIZE) +static int slub_debug = SLAB_POISON; #else static int slub_debug; #endif @@ -5755,6 +5757,11 @@ static int __init slab_sysfs_init(void) struct kmem_cache *s; int err; +#ifdef CONFIG_MEMORY_SANITIZE + pr_info("[CONFIG_MEMORY_SANITIZE]: slub_debug = P? %s [0x%x]\n", + slub_debug & SLAB_POISON ? "yes" : "no", slub_debug); +#endif + mutex_lock(&slab_mutex); slab_kset = kset_create_and_add("slab", &slab_uevent_ops, kernel_kobj); -- 2.7.4 -- Kees Cook Pixel Security
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.