From patchwork Sat Feb 25 00:32:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 9591393 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 744EF604A2 for ; Sat, 25 Feb 2017 00:32:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C0EE286AA for ; Sat, 25 Feb 2017 00:32:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D7C828697; Sat, 25 Feb 2017 00:32:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 1969D28697 for ; Sat, 25 Feb 2017 00:32:50 +0000 (UTC) Received: (qmail 30463 invoked by uid 550); 25 Feb 2017 00:32:48 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 30425 invoked from network); 25 Feb 2017 00:32:46 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:mime-version:content-disposition; bh=2IPJyqyoBctfAGlEcfaLQNXMz90x7sLyMRGzBg+0PEc=; b=EuM4ulL4KcVnZC9flyTruqEc4YKRQ0mOKvaYg+88U3W+lWNiYj6+B6IGdrJTvKRDd3 Hv2hBoCW9Ty+1iuPr+BkCoewrs/OVXwwNGRXYlm0DGki7IN4/dD+CHgvlhsZVPOdko/m toc1oPk0TU4XD6EwkhdH4GXbwc1jLDdQ4BUmQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition; bh=2IPJyqyoBctfAGlEcfaLQNXMz90x7sLyMRGzBg+0PEc=; b=gmqD/xQTTMK8+WAWNWNV1ptCItfu33BpjNI9JC9ojXkN0SnSRyh/y3X7fkbQEHMrHJ bsf+yfbxc0d4GB6TUHavoDoRW1CoMlqNcXeBCieHaeK5vr9Ckd0wqTMxVcCW8r8jnwnd N4pjEZmeHyjHtdFXJonmycJfxYqSe51/RzvPmSgSarhGrS28237aNgr2xzy3JHIa3Ucs FKfGXKOAVFko0o4/nKk0MR2DMyaIFzBy5LAHv1ijT0tSDLCJrV1kNqNC/etrGsb/Dk13 PTCk2MHXpYhmy50T0pXJo1BHypy7R6koMKTtkmy7VjUSLiDYVWx80GKBVItaW1YxwKzX 2HRg== X-Gm-Message-State: AMke39kZy9Dpyb6RSS19UV8/BEVKeDCYVbuoloRJMPyyYgLQWFpjG0UNelG/vFWP8aSFyIVR X-Received: by 10.84.176.100 with SMTP id u91mr7780434plb.112.1487982754110; Fri, 24 Feb 2017 16:32:34 -0800 (PST) Date: Fri, 24 Feb 2017 16:32:32 -0800 From: Kees Cook To: Kaiwan N Billimoria Cc: kernel-hardening@lists.openwall.com Message-ID: <20170225003232.GA123380@beast> MIME-Version: 1.0 Content-Disposition: inline Subject: [kernel-hardening] [RFC] mm: enable sanitizing via CONFIG X-Virus-Scanned: ClamAV using ClamSMTP This enables page and slab poisoning by default under CONFIG_MEMORY_SANITIZE. Based on work by Kaiwan N Billimoria. Signed-off-by: Kees Cook --- 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 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);