Commit 66cc69e34e86a231fbe68d8918c6119e3b7549a3
Committed by
Rusty Russell
1 parent
cff26a51da
Exists in
master
and in
13 other branches
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>
Showing 9 changed files with 20 additions and 5 deletions Side-by-side Diff
Documentation/ABI/testing/sysfs-module
Documentation/module-signing.txt
... | ... | @@ -53,7 +53,8 @@ |
53 | 53 | |
54 | 54 | If this is off (ie. "permissive"), then modules for which the key is not |
55 | 55 | available and modules that are unsigned are permitted, but the kernel will |
56 | - be marked as being tainted. | |
56 | + be marked as being tainted, and the concerned modules will be marked as | |
57 | + tainted, shown with the character 'X'. | |
57 | 58 | |
58 | 59 | If this is on (ie. "restrictive"), only modules that have a valid |
59 | 60 | signature that can be verified by a public key in the kernel's possession |
Documentation/oops-tracing.txt
... | ... | @@ -265,6 +265,9 @@ |
265 | 265 | |
266 | 266 | 13: 'O' if an externally-built ("out-of-tree") module has been loaded. |
267 | 267 | |
268 | + 14: 'X' if an unsigned module has been loaded in a kernel supporting | |
269 | + module signature. | |
270 | + | |
268 | 271 | The primary reason for the 'Tainted: ' string is to tell kernel |
269 | 272 | debuggers if this is a clean kernel or if anything unusual has |
270 | 273 | occurred. Tainting is permanent: even if an offending module is |
Documentation/sysctl/kernel.txt
... | ... | @@ -792,6 +792,8 @@ |
792 | 792 | 1024 - A module from drivers/staging was loaded. |
793 | 793 | 2048 - The system is working around a severe firmware bug. |
794 | 794 | 4096 - An out-of-tree module has been loaded. |
795 | +8192 - An unsigned module has been loaded in a kernel supporting module | |
796 | + signature. | |
795 | 797 | |
796 | 798 | ============================================================== |
797 | 799 |
include/linux/kernel.h
include/trace/events/module.h
... | ... | @@ -22,8 +22,10 @@ |
22 | 22 | |
23 | 23 | #define show_module_flags(flags) __print_flags(flags, "", \ |
24 | 24 | { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ |
25 | + { (1UL << TAINT_OOT_MODULE), "O" }, \ | |
25 | 26 | { (1UL << TAINT_FORCED_MODULE), "F" }, \ |
26 | - { (1UL << TAINT_CRAP), "C" }) | |
27 | + { (1UL << TAINT_CRAP), "C" }, \ | |
28 | + { (1UL << TAINT_UNSIGNED_MODULE), "X" }) | |
27 | 29 | |
28 | 30 | TRACE_EVENT(module_load, |
29 | 31 |
kernel/module.c
... | ... | @@ -1013,6 +1013,8 @@ |
1013 | 1013 | buf[l++] = 'F'; |
1014 | 1014 | if (mod->taints & (1 << TAINT_CRAP)) |
1015 | 1015 | buf[l++] = 'C'; |
1016 | + if (mod->taints & (1 << TAINT_UNSIGNED_MODULE)) | |
1017 | + buf[l++] = 'X'; | |
1016 | 1018 | /* |
1017 | 1019 | * TAINT_FORCED_RMMOD: could be added. |
1018 | 1020 | * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't |
... | ... | @@ -3214,7 +3216,7 @@ |
3214 | 3216 | pr_notice_once("%s: module verification failed: signature " |
3215 | 3217 | "and/or required key missing - tainting " |
3216 | 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 | 3221 | #endif |
3220 | 3222 |
kernel/panic.c
... | ... | @@ -210,6 +210,7 @@ |
210 | 210 | { TAINT_CRAP, 'C', ' ' }, |
211 | 211 | { TAINT_FIRMWARE_WORKAROUND, 'I', ' ' }, |
212 | 212 | { TAINT_OOT_MODULE, 'O', ' ' }, |
213 | + { TAINT_UNSIGNED_MODULE, 'X', ' ' }, | |
213 | 214 | }; |
214 | 215 | |
215 | 216 | /** |
... | ... | @@ -228,6 +229,7 @@ |
228 | 229 | * 'C' - modules from drivers/staging are loaded. |
229 | 230 | * 'I' - Working around severe firmware bug. |
230 | 231 | * 'O' - Out-of-tree module has been loaded. |
232 | + * 'X' - Unsigned module has been loaded. | |
231 | 233 | * |
232 | 234 | * The string is overwritten by the next call to print_tainted(). |
233 | 235 | */ |
kernel/tracepoint.c
... | ... | @@ -633,7 +633,8 @@ |
633 | 633 | #ifdef CONFIG_MODULES |
634 | 634 | bool 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 | |
639 | 640 | static int tracepoint_module_coming(struct module *mod) |
... | ... | @@ -644,7 +645,7 @@ |
644 | 645 | /* |
645 | 646 | * We skip modules that taint the kernel, especially those with different |
646 | 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 | 650 | if (trace_module_has_bad_taint(mod)) |
650 | 651 | return 0; |