summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2005-03-07 17:48:29 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-07 17:48:29 -0800
commit02721572728cccd31b54d69e1dfb8124fa02407e (patch)
tree690a586c7bbd524193c0f969583f3bc2e86cce9b /include/linux
parent69bfca0e64ca97d1a3063687e26fa0191ae3ddfd (diff)
[PATCH] Fix kallsyms/insmod/rmmod race
The attached patch fixes a race between kallsyms and insmod/rmmod. The problem is this: (1) The various kallsyms functions poke around in the module list without any locking so that they can be called from the oops handler. (2) Although insmod and rmmod use locks to exclude each other, these have no effect on the kallsyms function. (3) Although rmmod modifies the module state with the machine "stopped", it hasn't removed the metadata from the module metadata list, meaning that as soon as the machine is "restarted", the metadata can be observed by kallsyms. It's not possible to say that an item in that list should be ignored if it's state is marked as inactive - you can't get at the state information because you can't trust the metadata in which it is embedded. Furthermore, list linkage information is embedded in the metadata too, so you can't trust that either... (4) kallsyms may be walking the module list without a lock whilst either insmod or rmmod are busy changing it. insmod probably isn't a problem since nothing is going a way, but rmmod is as it's deleting an entry. (5) Therefore nothing that uses these functions can in any way trust any pointers to "static" data (such as module symbol names or module names) that are returned. (6) On ppc64 the problems are exacerbated since the hypervisor may reschedule bits of the kernel, making operations that appear adjacent occur a long time apart. This patch fixes the race by only linking/unlinking modules into/from the master module list with the machine in the "stopped" state. This means that any "static" information can be trusted as far as the next kernel reschedule on any given CPU without the need to hold any locks. However, I'm not sure how this is affected by preemption. I suspect more work may need to be done in that case, but I'm not entirely sure. This also means that rmmod has to bump the machine into the stopped state twice... but since that shouldn't be a common operation, I don't think that's a problem. I've amended this patch to not get spinlocks whilst in the machine locked state - there's no point as nothing else can be holding spinlocks. Signed-Off-By: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/stop_machine.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h
index 6f43cb53f21b..151a803ed0ed 100644
--- a/include/linux/stop_machine.h
+++ b/include/linux/stop_machine.h
@@ -8,7 +8,7 @@
#include <linux/cpu.h>
#include <asm/system.h>
-#ifdef CONFIG_SMP
+#if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP)
/**
* stop_machine_run: freeze the machine on all CPUs and run this function
* @fn: the function to run