+++ /dev/null
-From 5336377d6225959624146629ce3fc88ee8ecda3d Mon Sep 17 00:00:00 2001
-From: Linus Torvalds <torvalds@linux-foundation.org>
-Date: Tue, 5 Oct 2010 11:29:27 -0700
-Subject: modules: Fix module_bug_list list corruption race
-
-From: Linus Torvalds <torvalds@linux-foundation.org>
-
-commit 5336377d6225959624146629ce3fc88ee8ecda3d upstream.
-
-With all the recent module loading cleanups, we've minimized the code
-that sits under module_mutex, fixing various deadlocks and making it
-possible to do most of the module loading in parallel.
-
-However, that whole conversion totally missed the rather obscure code
-that adds a new module to the list for BUG() handling. That code was
-doubly obscure because (a) the code itself lives in lib/bugs.c (for
-dubious reasons) and (b) it gets called from the architecture-specific
-"module_finalize()" rather than from generic code.
-
-Calling it from arch-specific code makes no sense what-so-ever to begin
-with, and is now actively wrong since that code isn't protected by the
-module loading lock any more.
-
-So this commit moves the "module_bug_{finalize,cleanup}()" calls away
-from the arch-specific code, and into the generic code - and in the
-process protects it with the module_mutex so that the list operations
-are now safe.
-
-Future fixups:
- - move the module list handling code into kernel/module.c where it
- belongs.
- - get rid of 'module_bug_list' and just use the regular list of modules
- (called 'modules' - imagine that) that we already create and maintain
- for other reasons.
-
-Reported-and-tested-by: Thomas Gleixner <tglx@linutronix.de>
-Cc: Rusty Russell <rusty@rustcorp.com.au>
-Cc: Adrian Bunk <bunk@kernel.org>
-Cc: Andrew Morton <akpm@linux-foundation.org>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- arch/avr32/kernel/module.c | 3 +--
- arch/h8300/kernel/module.c | 3 +--
- arch/mn10300/kernel/module.c | 3 +--
- arch/parisc/kernel/module.c | 3 +--
- arch/powerpc/kernel/module.c | 5 -----
- arch/s390/kernel/module.c | 3 +--
- arch/sh/kernel/module.c | 2 --
- arch/x86/kernel/module.c | 3 +--
- include/linux/module.h | 5 ++---
- kernel/module.c | 4 ++++
- lib/bug.c | 6 ++----
- 11 files changed, 14 insertions(+), 26 deletions(-)
-
---- a/arch/avr32/kernel/module.c
-+++ b/arch/avr32/kernel/module.c
-@@ -314,10 +314,9 @@ int module_finalize(const Elf_Ehdr *hdr,
- vfree(module->arch.syminfo);
- module->arch.syminfo = NULL;
-
-- return module_bug_finalize(hdr, sechdrs, module);
-+ return 0;
- }
-
- void module_arch_cleanup(struct module *module)
- {
-- module_bug_cleanup(module);
- }
---- a/arch/h8300/kernel/module.c
-+++ b/arch/h8300/kernel/module.c
-@@ -112,10 +112,9 @@ int module_finalize(const Elf_Ehdr *hdr,
- const Elf_Shdr *sechdrs,
- struct module *me)
- {
-- return module_bug_finalize(hdr, sechdrs, me);
-+ return 0;
- }
-
- void module_arch_cleanup(struct module *mod)
- {
-- module_bug_cleanup(mod);
- }
---- a/arch/mn10300/kernel/module.c
-+++ b/arch/mn10300/kernel/module.c
-@@ -206,7 +206,7 @@ int module_finalize(const Elf_Ehdr *hdr,
- const Elf_Shdr *sechdrs,
- struct module *me)
- {
-- return module_bug_finalize(hdr, sechdrs, me);
-+ return 0;
- }
-
- /*
-@@ -214,5 +214,4 @@ int module_finalize(const Elf_Ehdr *hdr,
- */
- void module_arch_cleanup(struct module *mod)
- {
-- module_bug_cleanup(mod);
- }
---- a/arch/parisc/kernel/module.c
-+++ b/arch/parisc/kernel/module.c
-@@ -941,11 +941,10 @@ int module_finalize(const Elf_Ehdr *hdr,
- nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
- DEBUGP("NEW num_symtab %lu\n", nsyms);
- symhdr->sh_size = nsyms * sizeof(Elf_Sym);
-- return module_bug_finalize(hdr, sechdrs, me);
-+ return 0;
- }
-
- void module_arch_cleanup(struct module *mod)
- {
- deregister_unwind_table(mod);
-- module_bug_cleanup(mod);
- }
---- a/arch/powerpc/kernel/module.c
-+++ b/arch/powerpc/kernel/module.c
-@@ -65,10 +65,6 @@ int module_finalize(const Elf_Ehdr *hdr,
- const Elf_Shdr *sect;
- int err;
-
-- err = module_bug_finalize(hdr, sechdrs, me);
-- if (err)
-- return err;
--
- /* Apply feature fixups */
- sect = find_section(hdr, sechdrs, "__ftr_fixup");
- if (sect != NULL)
-@@ -101,5 +97,4 @@ int module_finalize(const Elf_Ehdr *hdr,
-
- void module_arch_cleanup(struct module *mod)
- {
-- module_bug_cleanup(mod);
- }
---- a/arch/s390/kernel/module.c
-+++ b/arch/s390/kernel/module.c
-@@ -407,10 +407,9 @@ int module_finalize(const Elf_Ehdr *hdr,
- {
- vfree(me->arch.syminfo);
- me->arch.syminfo = NULL;
-- return module_bug_finalize(hdr, sechdrs, me);
-+ return 0;
- }
-
- void module_arch_cleanup(struct module *mod)
- {
-- module_bug_cleanup(mod);
- }
---- a/arch/sh/kernel/module.c
-+++ b/arch/sh/kernel/module.c
-@@ -149,13 +149,11 @@ int module_finalize(const Elf_Ehdr *hdr,
- int ret = 0;
-
- ret |= module_dwarf_finalize(hdr, sechdrs, me);
-- ret |= module_bug_finalize(hdr, sechdrs, me);
-
- return ret;
- }
-
- void module_arch_cleanup(struct module *mod)
- {
-- module_bug_cleanup(mod);
- module_dwarf_cleanup(mod);
- }
---- a/arch/x86/kernel/module.c
-+++ b/arch/x86/kernel/module.c
-@@ -239,11 +239,10 @@ int module_finalize(const Elf_Ehdr *hdr,
- apply_paravirt(pseg, pseg + para->sh_size);
- }
-
-- return module_bug_finalize(hdr, sechdrs, me);
-+ return 0;
- }
-
- void module_arch_cleanup(struct module *mod)
- {
- alternatives_smp_module_del(mod);
-- module_bug_cleanup(mod);
- }
---- a/include/linux/module.h
-+++ b/include/linux/module.h
-@@ -686,17 +686,16 @@ extern int module_sysfs_initialized;
-
-
- #ifdef CONFIG_GENERIC_BUG
--int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *,
-+void module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *,
- struct module *);
- void module_bug_cleanup(struct module *);
-
- #else /* !CONFIG_GENERIC_BUG */
-
--static inline int module_bug_finalize(const Elf_Ehdr *hdr,
-+static inline void module_bug_finalize(const Elf_Ehdr *hdr,
- const Elf_Shdr *sechdrs,
- struct module *mod)
- {
-- return 0;
- }
- static inline void module_bug_cleanup(struct module *mod) {}
- #endif /* CONFIG_GENERIC_BUG */
---- a/kernel/module.c
-+++ b/kernel/module.c
-@@ -1533,6 +1533,7 @@ static int __unlink_module(void *_mod)
- {
- struct module *mod = _mod;
- list_del(&mod->list);
-+ module_bug_cleanup(mod);
- return 0;
- }
-
-@@ -2538,6 +2539,7 @@ static noinline struct module *load_modu
- if (err < 0)
- goto ddebug;
-
-+ module_bug_finalize(info.hdr, info.sechdrs, mod);
- list_add_rcu(&mod->list, &modules);
- mutex_unlock(&module_mutex);
-
-@@ -2564,6 +2566,8 @@ static noinline struct module *load_modu
- mutex_lock(&module_mutex);
- /* Unlink carefully: kallsyms could be walking list. */
- list_del_rcu(&mod->list);
-+ module_bug_cleanup(mod);
-+
- ddebug:
- dynamic_debug_remove(debug);
- unlock:
---- a/lib/bug.c
-+++ b/lib/bug.c
-@@ -72,8 +72,8 @@ static const struct bug_entry *module_fi
- return NULL;
- }
-
--int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
-- struct module *mod)
-+void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
-+ struct module *mod)
- {
- char *secstrings;
- unsigned int i;
-@@ -97,8 +97,6 @@ int module_bug_finalize(const Elf_Ehdr *
- * could potentially lead to deadlock and thus be counter-productive.
- */
- list_add(&mod->bug_list, &module_bug_list);
--
-- return 0;
- }
-
- void module_bug_cleanup(struct module *mod)