From patchwork Tue Oct 18 06:09:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 9381307 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 0B1DE60487 for ; Tue, 18 Oct 2016 06:02:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F34F5291D3 for ; Tue, 18 Oct 2016 06:02:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E7BA6292F5; Tue, 18 Oct 2016 06:02:14 +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 3BDCF291D3 for ; Tue, 18 Oct 2016 06:02:11 +0000 (UTC) Received: (qmail 19594 invoked by uid 550); 18 Oct 2016 06:02:09 -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: Reply-To: kernel-hardening@lists.openwall.com Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 19559 invoked from network); 18 Oct 2016 06:02:07 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:subject:message-id:mail-followup-to:mime-version :content-disposition:user-agent; bh=OAriAa3AyCsRpZYFGfcv27KlpZRrNpmuQJP1CnuJhJ8=; b=EOkeE0zDwtiiONYmqh0qM+ycTVkCDgSlBaySJdF7WI4/y1zcyzFKV+g2In2OVt4UaA OV0Iaw/2dc3LYuVqEz6wXdQMVVPHbYL5i4mBu0HhJZb4vfbjtlq5PqKjNgX3/tp7EiFR qcfqdU1h+YASwWIlHR5G+YyKHe/+JAenTb2n8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:subject:message-id:mail-followup-to :mime-version:content-disposition:user-agent; bh=OAriAa3AyCsRpZYFGfcv27KlpZRrNpmuQJP1CnuJhJ8=; b=ctdOW9B17lVPoHQBVkiz/4SSyXyFT1+HDsF9bdj2N1tne7IP7DwM0st1zfh08k9vp/ KrClNladV4eJSjxLZbECI8SLmhxvNeFdgl/hTLq/HIe0V177w3pbATdsRSaOAqbjUdkp yvc05m8HEUS+QxK/JjWlIB2JPl2xVBLgN+qEEXXPIEjhGCMbHFe/yUBr5a51qdRBG0cu AG84R1+RbW+PmmwjsCzKjuliCu41/SUTJSvyZCZuu8TRN2Tpknpa6IssK5n5wvzrkIWq 9qdYF3PfGCsdjadBHqgvmWIIAtnAu5v2xeHxmstTfQpEcBcA/a94L99Q96p81Al0Rhps CMIg== X-Gm-Message-State: AA6/9RlGLKgH173+eLn/qzWIW1PKQ/8FnnR4sav1IOKJeOHivq31xJ3gtuLq1I+Ngn4+E/Qy X-Received: by 10.99.98.5 with SMTP id w5mr1498245pgb.77.1476770515143; Mon, 17 Oct 2016 23:01:55 -0700 (PDT) Date: Tue, 18 Oct 2016 15:09:51 +0900 From: AKASHI Takahiro To: kernel-hardening@lists.openwall.com, linux-kernel@vger.kernel.org Message-ID: <20161018060950.GM19531@linaro.org> Mail-Followup-To: AKASHI Takahiro , kernel-hardening@lists.openwall.com, linux-kernel@vger.kernel.org MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) Subject: [kernel-hardening] [RFC] module: add 'module_ronx=off' boot cmdline parameter to disable ro/nx module mappings X-Virus-Scanned: ClamAV using ClamSMTP As making CONFIG_DEBUG_RODATA mandatory is a good idea, so will be for CONFIG_SET_MODULE_RONX. This patch adds a command line parameter, "module_ronx=," in order to make this configuration always on in the future, but still allowing for disabling read-only module mappings at boot time as "rodata=" does. I have, however, some concerns on this prototype: (1) should we use a separate parameter like "module_ronx=," or unify it with "rodata="? (2) should we keep NX permission set even if module_ronx=off? I tested this patch with: - insmod lkdtm.ko cpoint_name=DIRECT cpoint_type="WRITE_KERN" - insmod lkdtm.ko cpoint_name=DIRECT cpoint_type="WRITE_RO" - insmod lkdtm.ko cpoint_name=DIRECT cpoint_type="EXEC_DATA" WRITE_RO_AFTER_INIT case doesn't fail because the test is executed *before* setting the ro_after_init data ro. Any comments are welcome. Thanks, -Takahiro AKASHI ===8<=== From aeb6bcdbe462251f5aab828ba58f2f64e9c51d69 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Thu, 13 Oct 2016 14:39:20 +0900 Subject: [RFC] module: add 'module_ronx=off' boot cmdline parameter to disable ro/nx module mappings "module_ronx=off" allows for writing to read-only module text as well as executing any code in data section (as if !CONFIG_SET_MODULE_RONX). It corresponds to the kernel patch: commit d2aa1acad22f ("mm/init: Add 'rodata=off' boot cmdline parameter to disable read-only kernel mappings") Signed-off-by: AKASHI Takahiro --- kernel/module.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index f57dd63..cc75ad6 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1855,6 +1855,9 @@ static void mod_sysfs_teardown(struct module *mod) } #ifdef CONFIG_DEBUG_SET_MODULE_RONX +static bool module_ronx_enabled = true; +core_param(module_ronx, module_ronx_enabled, bool, 0); + /* * LKM RO/NX protection: protect module's text/ro-data * from modification and any data from execution. @@ -1989,6 +1992,8 @@ static void disable_ro_nx(const struct module_layout *layout) } #else +#define module_ronx_enabled false + static void disable_ro_nx(const struct module_layout *layout) { } static void module_enable_nx(const struct module *mod) { } static void module_disable_nx(const struct module *mod) { } @@ -2124,7 +2129,8 @@ static void free_module(struct module *mod) mutex_unlock(&module_mutex); /* This may be empty, but that's OK */ - disable_ro_nx(&mod->init_layout); + if (module_ronx_enabled) + disable_ro_nx(&mod->init_layout); module_arch_freeing_init(mod); module_memfree(mod->init_layout.base); kfree(mod->args); @@ -2134,7 +2140,8 @@ static void free_module(struct module *mod) lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); /* Finally, free the core (containing the module structure) */ - disable_ro_nx(&mod->core_layout); + if (module_ronx_enabled) + disable_ro_nx(&mod->core_layout); module_memfree(mod->core_layout.base); #ifdef CONFIG_MPU @@ -3428,9 +3435,11 @@ static noinline int do_init_module(struct module *mod) /* Switch to core kallsyms now init is done: kallsyms may be walking! */ rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms); #endif - module_enable_ro(mod, true); + if (module_ronx_enabled) + module_enable_ro(mod, true); mod_tree_remove_init(mod); - disable_ro_nx(&mod->init_layout); + if (module_ronx_enabled) + disable_ro_nx(&mod->init_layout); module_arch_freeing_init(mod); mod->init_layout.base = NULL; mod->init_layout.size = 0; @@ -3527,8 +3536,10 @@ static int complete_formation(struct module *mod, struct load_info *info) /* This relies on module_mutex for list integrity. */ module_bug_finalize(info->hdr, info->sechdrs, mod); - module_enable_ro(mod, false); - module_enable_nx(mod); + if (module_ronx_enabled) { + module_enable_ro(mod, false); + module_enable_nx(mod); + } /* Mark state as coming so strong_try_module_get() ignores us, * but kallsyms etc. can see us. */ @@ -3718,8 +3729,10 @@ static int load_module(struct load_info *info, const char __user *uargs, mutex_unlock(&module_mutex); /* we can't deallocate the module until we clear memory protection */ - module_disable_ro(mod); - module_disable_nx(mod); + if (module_ronx_enabled) { + module_disable_ro(mod); + module_disable_nx(mod); + } ddebug_cleanup: dynamic_debug_remove(info->debug);