[kernel/f14] Backport 5336377d6225959624146629ce3fc88ee8ecda3d for RHBZ 648571
Josh Boyer
jwboyer at fedoraproject.org
Tue Sep 13 20:49:04 UTC 2011
commit cf5a635e41bb1b40c45f4c68611eab0ffe3d0980
Author: Josh Boyer <jwboyer at redhat.com>
Date: Mon Sep 12 10:59:49 2011 -0400
Backport 5336377d6225959624146629ce3fc88ee8ecda3d for RHBZ 648571
kernel.spec | 11 +-
...-Fix-module_bug_list-list-corruption-race.patch | 271 ++++++++++++++++++++
2 files changed, 281 insertions(+), 1 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 95ed6e0..cc12bce 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -48,7 +48,7 @@ Summary: The Linux kernel
# reset this by hand to 1 (or to 0 and then use rpmdev-bumpspec).
# scripts/rebase.sh should be made to do that for you, actually.
#
-%global baserelease 96
+%global baserelease 97
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@@ -861,6 +861,9 @@ Patch14040: asix-add-USB-ID-for-Logitec-LAN-GTJ-U2A.patch
# RHBZ #665109
Patch14050: x86-PCI-don-t-use-native-Broadcom-CNB20LE-driver-whe.patch
+# RHBZ #648571
+Patch14051: modules-Fix-module_bug_list-list-corruption-race.patch
+
%endif
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1621,6 +1624,9 @@ ApplyPatch asix-add-USB-ID-for-Logitec-LAN-GTJ-U2A.patch
# RHBZ #665109
ApplyPatch x86-PCI-don-t-use-native-Broadcom-CNB20LE-driver-whe.patch
+# RHBZ #648571
+ApplyPatch modules-Fix-module_bug_list-list-corruption-race.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2207,6 +2213,9 @@ fi
# and build.
%changelog
+* Mon Sep 12 2011 Josh Boyer <jwboyer at redhat.com>
+- Backport 5336377d to fix RHBZ #648571
+
* Wed Aug 31 2011 Josh Boyer <jwboyer at redhat.com> 2.6.35.14-96
- Add patch to fix RHBZ #665109
diff --git a/modules-Fix-module_bug_list-list-corruption-race.patch b/modules-Fix-module_bug_list-list-corruption-race.patch
new file mode 100644
index 0000000..ab62ae6
--- /dev/null
+++ b/modules-Fix-module_bug_list-list-corruption-race.patch
@@ -0,0 +1,271 @@
+From 9aad2d11106f9a42593ee8eb3f10bc469873a18e Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds at linux-foundation.org>
+Date: Tue, 5 Oct 2010 11:29:27 -0700
+Subject: [PATCH] modules: Fix module_bug_list list corruption race
+
+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 at linutronix.de>
+Cc: Rusty Russell <rusty at rustcorp.com.au>
+Cc: Adrian Bunk <bunk at kernel.org>
+Cc: Andrew Morton <akpm at linux-foundation.org>
+Cc: stable at kernel.org
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+---
+ 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(-)
+
+diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c
+index 98f94d0..a727f54 100644
+--- a/arch/avr32/kernel/module.c
++++ b/arch/avr32/kernel/module.c
+@@ -314,10 +314,9 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
+ 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);
+ }
+diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c
+index 0865e29..db4953d 100644
+--- 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);
+ }
+diff --git a/arch/mn10300/kernel/module.c b/arch/mn10300/kernel/module.c
+index 6aea7fd..196a111 100644
+--- 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);
+ }
+diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
+index 159a2b8..6e81bb5 100644
+--- 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);
+ }
+diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
+index 477c663..4ef93ae 100644
+--- 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);
+ }
+diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
+index 22cfd63..f7167ee 100644
+--- 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);
+ }
+diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
+index 43adddf..ae0be69 100644
+--- 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);
+ }
+diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
+index e0bc186..1c355c5 100644
+--- 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);
+ }
+diff --git a/include/linux/module.h b/include/linux/module.h
+index 8a6b9fd..aace066 100644
+--- 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 */
+diff --git a/kernel/module.c b/kernel/module.c
+index 6c56282..eca6e02 100644
+--- 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_module(void __user *umod,
+ if (err < 0)
+ goto ddebug;
+
++ module_bug_finalize(hdr, sechdrs, mod);
+ list_add_rcu(&mod->list, &modules);
+ mutex_unlock(&module_mutex);
+
+@@ -2564,6 +2566,8 @@ static noinline struct module *load_module(void __user *umod,
+ 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:
+diff --git a/lib/bug.c b/lib/bug.c
+index f13daf4..c005615 100644
+--- a/lib/bug.c
++++ b/lib/bug.c
+@@ -72,8 +72,8 @@ static const struct bug_entry *module_find_bug(unsigned long bugaddr)
+ 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 *hdr, const Elf_Shdr *sechdrs,
+ * 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)
+--
+1.7.6
+
More information about the scm-commits
mailing list