kernel-hardening.lists.openwall.com archive mirror
 help / color / mirror / Atom feed
From: tip-bot for Rick Edgecombe <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: tglx@linutronix.de, bp@alien8.de, mingo@kernel.org,
	deneen.t.dock@intel.com, peterz@infradead.org,
	will.deacon@arm.com, linux_dti@icloud.com,
	linux-kernel@vger.kernel.org,
	kernel-hardening@lists.openwall.com, kristen@linux.intel.com,
	rostedt@goodmis.org, akpm@linux-foundation.org,
	dave.hansen@linux.intel.com, rick.p.edgecombe@intel.com,
	nadav.amit@gmail.com, ard.biesheuvel@linaro.org, luto@kernel.org,
	hpa@zytor.com, jeyu@kernel.org, torvalds@linux-foundation.org,
	riel@surriel.com
Subject: [tip:x86/mm] modules: Use vmalloc special flag
Date: Tue, 30 Apr 2019 04:26:53 -0700	[thread overview]
Message-ID: <tip-1a7b7d9220819afe79d1ec5d759fe4349bd2453e@git.kernel.org> (raw)
In-Reply-To: <20190426001143.4983-18-namit@vmware.com>

Commit-ID:  1a7b7d9220819afe79d1ec5d759fe4349bd2453e
Gitweb:     https://git.kernel.org/tip/1a7b7d9220819afe79d1ec5d759fe4349bd2453e
Author:     Rick Edgecombe <rick.p.edgecombe@intel.com>
AuthorDate: Thu, 25 Apr 2019 17:11:37 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 30 Apr 2019 12:37:58 +0200

modules: Use vmalloc special flag

Use new flag for handling freeing of special permissioned memory in vmalloc
and remove places where memory was set RW before freeing which is no longer
needed.

Since freeing of VM_FLUSH_RESET_PERMS memory is not supported in an
interrupt by vmalloc, the freeing of init sections is moved to a work
queue. Instead of call_rcu it now uses synchronize_rcu() in the work
queue.

Lastly, there is now a WARN_ON in module_memfree since it should not be
called in an interrupt with special memory as is required for
VM_FLUSH_RESET_PERMS.

Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: <akpm@linux-foundation.org>
Cc: <ard.biesheuvel@linaro.org>
Cc: <deneen.t.dock@intel.com>
Cc: <kernel-hardening@lists.openwall.com>
Cc: <kristen@linux.intel.com>
Cc: <linux_dti@icloud.com>
Cc: <will.deacon@arm.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jessica Yu <jeyu@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <nadav.amit@gmail.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20190426001143.4983-18-namit@vmware.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/module.c | 77 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 39 insertions(+), 38 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 2b2845ae983e..a9020bdd4cf6 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -98,6 +98,10 @@ DEFINE_MUTEX(module_mutex);
 EXPORT_SYMBOL_GPL(module_mutex);
 static LIST_HEAD(modules);
 
+/* Work queue for freeing init sections in success case */
+static struct work_struct init_free_wq;
+static struct llist_head init_free_list;
+
 #ifdef CONFIG_MODULES_TREE_LOOKUP
 
 /*
@@ -1949,6 +1953,8 @@ void module_enable_ro(const struct module *mod, bool after_init)
 	if (!rodata_enabled)
 		return;
 
+	set_vm_flush_reset_perms(mod->core_layout.base);
+	set_vm_flush_reset_perms(mod->init_layout.base);
 	frob_text(&mod->core_layout, set_memory_ro);
 	frob_text(&mod->core_layout, set_memory_x);
 
@@ -1972,15 +1978,6 @@ static void module_enable_nx(const struct module *mod)
 	frob_writable_data(&mod->init_layout, set_memory_nx);
 }
 
-static void module_disable_nx(const struct module *mod)
-{
-	frob_rodata(&mod->core_layout, set_memory_x);
-	frob_ro_after_init(&mod->core_layout, set_memory_x);
-	frob_writable_data(&mod->core_layout, set_memory_x);
-	frob_rodata(&mod->init_layout, set_memory_x);
-	frob_writable_data(&mod->init_layout, set_memory_x);
-}
-
 /* Iterate through all modules and set each module's text as RW */
 void set_all_modules_text_rw(void)
 {
@@ -2024,23 +2021,8 @@ void set_all_modules_text_ro(void)
 	}
 	mutex_unlock(&module_mutex);
 }
-
-static void disable_ro_nx(const struct module_layout *layout)
-{
-	if (rodata_enabled) {
-		frob_text(layout, set_memory_rw);
-		frob_rodata(layout, set_memory_rw);
-		frob_ro_after_init(layout, set_memory_rw);
-	}
-	frob_rodata(layout, set_memory_x);
-	frob_ro_after_init(layout, set_memory_x);
-	frob_writable_data(layout, set_memory_x);
-}
-
 #else
-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) { }
 #endif
 
 #ifdef CONFIG_LIVEPATCH
@@ -2120,6 +2102,11 @@ static void free_module_elf(struct module *mod)
 
 void __weak module_memfree(void *module_region)
 {
+	/*
+	 * This memory may be RO, and freeing RO memory in an interrupt is not
+	 * supported by vmalloc.
+	 */
+	WARN_ON(in_interrupt());
 	vfree(module_region);
 }
 
@@ -2171,7 +2158,6 @@ 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);
 	module_arch_freeing_init(mod);
 	module_memfree(mod->init_layout.base);
 	kfree(mod->args);
@@ -2181,7 +2167,6 @@ 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);
 	module_memfree(mod->core_layout.base);
 }
 
@@ -3420,17 +3405,34 @@ static void do_mod_ctors(struct module *mod)
 
 /* For freeing module_init on success, in case kallsyms traversing */
 struct mod_initfree {
-	struct rcu_head rcu;
+	struct llist_node node;
 	void *module_init;
 };
 
-static void do_free_init(struct rcu_head *head)
+static void do_free_init(struct work_struct *w)
 {
-	struct mod_initfree *m = container_of(head, struct mod_initfree, rcu);
-	module_memfree(m->module_init);
-	kfree(m);
+	struct llist_node *pos, *n, *list;
+	struct mod_initfree *initfree;
+
+	list = llist_del_all(&init_free_list);
+
+	synchronize_rcu();
+
+	llist_for_each_safe(pos, n, list) {
+		initfree = container_of(pos, struct mod_initfree, node);
+		module_memfree(initfree->module_init);
+		kfree(initfree);
+	}
 }
 
+static int __init modules_wq_init(void)
+{
+	INIT_WORK(&init_free_wq, do_free_init);
+	init_llist_head(&init_free_list);
+	return 0;
+}
+module_init(modules_wq_init);
+
 /*
  * This is where the real work happens.
  *
@@ -3507,7 +3509,6 @@ static noinline int do_init_module(struct module *mod)
 #endif
 	module_enable_ro(mod, true);
 	mod_tree_remove_init(mod);
-	disable_ro_nx(&mod->init_layout);
 	module_arch_freeing_init(mod);
 	mod->init_layout.base = NULL;
 	mod->init_layout.size = 0;
@@ -3518,14 +3519,18 @@ static noinline int do_init_module(struct module *mod)
 	 * We want to free module_init, but be aware that kallsyms may be
 	 * walking this with preempt disabled.  In all the failure paths, we
 	 * call synchronize_rcu(), but we don't want to slow down the success
-	 * path, so use actual RCU here.
+	 * path. module_memfree() cannot be called in an interrupt, so do the
+	 * work and call synchronize_rcu() in a work queue.
+	 *
 	 * Note that module_alloc() on most architectures creates W+X page
 	 * mappings which won't be cleaned up until do_free_init() runs.  Any
 	 * code such as mark_rodata_ro() which depends on those mappings to
 	 * be cleaned up needs to sync with the queued work - ie
 	 * rcu_barrier()
 	 */
-	call_rcu(&freeinit->rcu, do_free_init);
+	if (llist_add(&freeinit->node, &init_free_list))
+		schedule_work(&init_free_wq);
+
 	mutex_unlock(&module_mutex);
 	wake_up_all(&module_wq);
 
@@ -3822,10 +3827,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
 	module_bug_cleanup(mod);
 	mutex_unlock(&module_mutex);
 
-	/* we can't deallocate the module until we clear memory protection */
-	module_disable_ro(mod);
-	module_disable_nx(mod);
-
  ddebug_cleanup:
 	ftrace_release_mod(mod);
 	dynamic_debug_remove(mod, info->debug);

  reply	other threads:[~2019-04-30 11:26 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-26  0:11 [PATCH v5 00/23] x86: text_poke() fixes and executable lockdowns Nadav Amit
2019-04-26  0:11 ` [PATCH v5 01/23] Fix "x86/alternatives: Lockdep-enforce text_mutex in text_poke*()" Nadav Amit
2019-04-30 11:13   ` [tip:x86/mm] x86/alternatives: Add text_poke_kgdb() to not assert the lock when debugging tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 02/23] x86/jump_label: Use text_poke_early() during early init Nadav Amit
2019-04-30 11:15   ` [tip:x86/mm] " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 03/23] x86/mm: Introduce temporary mm structs Nadav Amit
2019-04-30 11:16   ` [tip:x86/mm] " tip-bot for Andy Lutomirski
2019-04-26  0:11 ` [PATCH v5 04/23] x86/mm: Save debug registers when loading a temporary mm Nadav Amit
2019-04-30 11:17   ` [tip:x86/mm] " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 05/23] fork: Provide a function for copying init_mm Nadav Amit
2019-04-30 11:18   ` [tip:x86/mm] " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 06/23] x86/alternative: Initialize temporary mm for patching Nadav Amit
2019-04-26  0:11 ` [PATCH v5 07/23] x86/alternative: Use temporary mm for text poking Nadav Amit
2019-04-30 11:20   ` [tip:x86/mm] x86/alternatives: " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 08/23] x86/kgdb: Avoid redundant comparison of patched code Nadav Amit
2019-04-30 11:20   ` [tip:x86/mm] " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 09/23] x86/ftrace: Set trampoline pages as executable Nadav Amit
2019-04-30 11:21   ` [tip:x86/mm] " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 10/23] x86/kprobes: Set instruction page " Nadav Amit
2019-04-30 11:22   ` [tip:x86/mm] " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 11/23] x86/module: Avoid breaking W^X while loading modules Nadav Amit
2019-04-30 11:22   ` [tip:x86/mm] x86/modules: " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 12/23] x86/jump-label: Remove support for custom poker Nadav Amit
2019-04-30 11:23   ` [tip:x86/mm] x86/jump-label: Remove support for custom text poker tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 13/23] x86/alternative: Remove the return value of text_poke_*() Nadav Amit
2019-04-30 11:24   ` [tip:x86/mm] x86/alternatives: " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 14/23] x86/mm/cpa: Add set_direct_map_ functions Nadav Amit
2019-04-26 16:40   ` Linus Torvalds
2019-04-26 16:43     ` Nadav Amit
2019-04-30 11:24   ` [tip:x86/mm] x86/mm/cpa: Add set_direct_map_*() functions tip-bot for Rick Edgecombe
2019-04-26  0:11 ` [PATCH v5 15/23] mm: Make hibernate handle unmapped pages Nadav Amit
2019-04-30 11:25   ` [tip:x86/mm] mm/hibernation: Make hibernation " tip-bot for Rick Edgecombe
2019-04-26  0:11 ` [PATCH v5 16/23] vmalloc: Add flag for free of special permsissions Nadav Amit
2019-04-30 11:26   ` [tip:x86/mm] mm/vmalloc: Add flag for freeing " tip-bot for Rick Edgecombe
2019-04-26  0:11 ` [PATCH v5 17/23] modules: Use vmalloc special flag Nadav Amit
2019-04-30 11:26   ` tip-bot for Rick Edgecombe [this message]
2019-04-26  0:11 ` [PATCH v5 18/23] bpf: " Nadav Amit
2019-04-30 11:27   ` [tip:x86/mm] " tip-bot for Rick Edgecombe
2019-04-26  0:11 ` [PATCH v5 19/23] x86/ftrace: " Nadav Amit
2019-04-30 11:28   ` [tip:x86/mm] " tip-bot for Rick Edgecombe
2019-04-26  0:11 ` [PATCH v5 20/23] x86/kprobes: " Nadav Amit
2019-04-30 11:28   ` [tip:x86/mm] " tip-bot for Rick Edgecombe
2019-04-26  0:11 ` [PATCH v5 21/23] x86/alternative: Comment about module removal races Nadav Amit
2019-04-30 11:29   ` [tip:x86/mm] x86/alternatives: Add comment " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 22/23] mm/tlb: Provide default nmi_uaccess_okay() Nadav Amit
2019-04-30 11:14   ` [tip:x86/mm] " tip-bot for Nadav Amit
2019-04-26  0:11 ` [PATCH v5 23/23] bpf: Fail bpf_probe_write_user() while mm is switched Nadav Amit
2019-04-30 11:15   ` [tip:x86/mm] " tip-bot for Nadav Amit
2019-04-26 12:36 ` [PATCH v5 00/23] x86: text_poke() fixes and executable lockdowns Peter Zijlstra

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=tip-1a7b7d9220819afe79d1ec5d759fe4349bd2453e@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=akpm@linux-foundation.org \
    --cc=ard.biesheuvel@linaro.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=deneen.t.dock@intel.com \
    --cc=hpa@zytor.com \
    --cc=jeyu@kernel.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=kristen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=linux_dti@icloud.com \
    --cc=luto@kernel.org \
    --cc=mingo@kernel.org \
    --cc=nadav.amit@gmail.com \
    --cc=peterz@infradead.org \
    --cc=rick.p.edgecombe@intel.com \
    --cc=riel@surriel.com \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=will.deacon@arm.com \
    /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;
as well as URLs for NNTP newsgroup(s).