aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>2014-03-12 21:41:30 -0400
committerRusty Russell <rusty@rustcorp.com.au>2014-03-12 21:41:51 -0400
commit66cc69e34e86a231fbe68d8918c6119e3b7549a3 (patch)
treec1ea795511e9ed8ab83fda895f0151000b166629 /kernel
parentcff26a51da5d206d3baf871e75778da44710219d (diff)
Fix: module signature vs tracepoints: add new TAINT_UNSIGNED_MODULE
Users have reported being unable to trace non-signed modules loaded within a kernel supporting module signature. This is caused by tracepoint.c:tracepoint_module_coming() refusing to take into account tracepoints sitting within force-loaded modules (TAINT_FORCED_MODULE). The reason for this check, in the first place, is that a force-loaded module may have a struct module incompatible with the layout expected by the kernel, and can thus cause a kernel crash upon forced load of that module on a kernel with CONFIG_TRACEPOINTS=y. Tracepoints, however, specifically accept TAINT_OOT_MODULE and TAINT_CRAP, since those modules do not lead to the "very likely system crash" issue cited above for force-loaded modules. With kernels having CONFIG_MODULE_SIG=y (signed modules), a non-signed module is tainted re-using the TAINT_FORCED_MODULE taint flag. Unfortunately, this means that Tracepoints treat that module as a force-loaded module, and thus silently refuse to consider any tracepoint within this module. Since an unsigned module does not fit within the "very likely system crash" category of tainting, add a new TAINT_UNSIGNED_MODULE taint flag to specifically address this taint behavior, and accept those modules within Tracepoints. We use the letter 'X' as a taint flag character for a module being loaded that doesn't know how to sign its name (proposed by Steven Rostedt). Also add the missing 'O' entry to trace event show_module_flags() list for the sake of completeness. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Acked-by: Steven Rostedt <rostedt@goodmis.org> NAKed-by: Ingo Molnar <mingo@redhat.com> CC: Thomas Gleixner <tglx@linutronix.de> CC: David Howells <dhowells@redhat.com> CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/module.c4
-rw-r--r--kernel/panic.c2
-rw-r--r--kernel/tracepoint.c5
3 files changed, 8 insertions, 3 deletions
diff --git a/kernel/module.c b/kernel/module.c
index efa1e6031950..c1acb0c5b637 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1013,6 +1013,8 @@ static size_t module_flags_taint(struct module *mod, char *buf)
1013 buf[l++] = 'F'; 1013 buf[l++] = 'F';
1014 if (mod->taints & (1 << TAINT_CRAP)) 1014 if (mod->taints & (1 << TAINT_CRAP))
1015 buf[l++] = 'C'; 1015 buf[l++] = 'C';
1016 if (mod->taints & (1 << TAINT_UNSIGNED_MODULE))
1017 buf[l++] = 'X';
1016 /* 1018 /*
1017 * TAINT_FORCED_RMMOD: could be added. 1019 * TAINT_FORCED_RMMOD: could be added.
1018 * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't 1020 * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
@@ -3214,7 +3216,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
3214 pr_notice_once("%s: module verification failed: signature " 3216 pr_notice_once("%s: module verification failed: signature "
3215 "and/or required key missing - tainting " 3217 "and/or required key missing - tainting "
3216 "kernel\n", mod->name); 3218 "kernel\n", mod->name);
3217 add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_STILL_OK); 3219 add_taint_module(mod, TAINT_UNSIGNED_MODULE, LOCKDEP_STILL_OK);
3218 } 3220 }
3219#endif 3221#endif
3220 3222
diff --git a/kernel/panic.c b/kernel/panic.c
index 6d6300375090..0e25fe10871e 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -210,6 +210,7 @@ static const struct tnt tnts[] = {
210 { TAINT_CRAP, 'C', ' ' }, 210 { TAINT_CRAP, 'C', ' ' },
211 { TAINT_FIRMWARE_WORKAROUND, 'I', ' ' }, 211 { TAINT_FIRMWARE_WORKAROUND, 'I', ' ' },
212 { TAINT_OOT_MODULE, 'O', ' ' }, 212 { TAINT_OOT_MODULE, 'O', ' ' },
213 { TAINT_UNSIGNED_MODULE, 'X', ' ' },
213}; 214};
214 215
215/** 216/**
@@ -228,6 +229,7 @@ static const struct tnt tnts[] = {
228 * 'C' - modules from drivers/staging are loaded. 229 * 'C' - modules from drivers/staging are loaded.
229 * 'I' - Working around severe firmware bug. 230 * 'I' - Working around severe firmware bug.
230 * 'O' - Out-of-tree module has been loaded. 231 * 'O' - Out-of-tree module has been loaded.
232 * 'X' - Unsigned module has been loaded.
231 * 233 *
232 * The string is overwritten by the next call to print_tainted(). 234 * The string is overwritten by the next call to print_tainted().
233 */ 235 */
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 031cc5655a51..3cdbed1fbdc7 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -633,7 +633,8 @@ EXPORT_SYMBOL_GPL(tracepoint_iter_reset);
633#ifdef CONFIG_MODULES 633#ifdef CONFIG_MODULES
634bool trace_module_has_bad_taint(struct module *mod) 634bool trace_module_has_bad_taint(struct module *mod)
635{ 635{
636 return mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP)); 636 return mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP) |
637 (1 << TAINT_UNSIGNED_MODULE));
637} 638}
638 639
639static int tracepoint_module_coming(struct module *mod) 640static int tracepoint_module_coming(struct module *mod)
@@ -644,7 +645,7 @@ static int tracepoint_module_coming(struct module *mod)
644 /* 645 /*
645 * We skip modules that taint the kernel, especially those with different 646 * We skip modules that taint the kernel, especially those with different
646 * module headers (for forced load), to make sure we don't cause a crash. 647 * module headers (for forced load), to make sure we don't cause a crash.
647 * Staging and out-of-tree GPL modules are fine. 648 * Staging, out-of-tree, and unsigned GPL modules are fine.
648 */ 649 */
649 if (trace_module_has_bad_taint(mod)) 650 if (trace_module_has_bad_taint(mod))
650 return 0; 651 return 0;