aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/ABI/testing/sysfs-module1
-rw-r--r--Documentation/module-signing.txt3
-rw-r--r--Documentation/oops-tracing.txt3
-rw-r--r--Documentation/sysctl/kernel.txt2
-rw-r--r--include/linux/kernel.h1
-rw-r--r--include/trace/events/module.h4
-rw-r--r--kernel/module.c4
-rw-r--r--kernel/panic.c2
-rw-r--r--kernel/tracepoint.c5
9 files changed, 20 insertions, 5 deletions
diff --git a/Documentation/ABI/testing/sysfs-module b/Documentation/ABI/testing/sysfs-module
index 47064c2b1f79..b9a29cdbaccb 100644
--- a/Documentation/ABI/testing/sysfs-module
+++ b/Documentation/ABI/testing/sysfs-module
@@ -49,3 +49,4 @@ Description: Module taint flags:
49 O - out-of-tree module 49 O - out-of-tree module
50 F - force-loaded module 50 F - force-loaded module
51 C - staging driver module 51 C - staging driver module
52 X - unsigned module
diff --git a/Documentation/module-signing.txt b/Documentation/module-signing.txt
index 2b40e04d3c49..b6af42e4d790 100644
--- a/Documentation/module-signing.txt
+++ b/Documentation/module-signing.txt
@@ -53,7 +53,8 @@ This has a number of options available:
53 53
54 If this is off (ie. "permissive"), then modules for which the key is not 54 If this is off (ie. "permissive"), then modules for which the key is not
55 available and modules that are unsigned are permitted, but the kernel will 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 If this is on (ie. "restrictive"), only modules that have a valid 59 If this is on (ie. "restrictive"), only modules that have a valid
59 signature that can be verified by a public key in the kernel's possession 60 signature that can be verified by a public key in the kernel's possession
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index 13032c0140d4..879abe289523 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -265,6 +265,9 @@ characters, each representing a particular tainted value.
265 265
266 13: 'O' if an externally-built ("out-of-tree") module has been loaded. 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
268The primary reason for the 'Tainted: ' string is to tell kernel 271The primary reason for the 'Tainted: ' string is to tell kernel
269debuggers if this is a clean kernel or if anything unusual has 272debuggers if this is a clean kernel or if anything unusual has
270occurred. Tainting is permanent: even if an offending module is 273occurred. Tainting is permanent: even if an offending module is
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index e55124e7c40c..8ebe1c047004 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -792,6 +792,8 @@ can be ORed together:
7921024 - A module from drivers/staging was loaded. 7921024 - A module from drivers/staging was loaded.
7932048 - The system is working around a severe firmware bug. 7932048 - The system is working around a severe firmware bug.
7944096 - An out-of-tree module has been loaded. 7944096 - An out-of-tree module has been loaded.
7958192 - An unsigned module has been loaded in a kernel supporting module
796 signature.
795 797
796============================================================== 798==============================================================
797 799
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 196d1ea86df0..471090093c67 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -469,6 +469,7 @@ extern enum system_states {
469#define TAINT_CRAP 10 469#define TAINT_CRAP 10
470#define TAINT_FIRMWARE_WORKAROUND 11 470#define TAINT_FIRMWARE_WORKAROUND 11
471#define TAINT_OOT_MODULE 12 471#define TAINT_OOT_MODULE 12
472#define TAINT_UNSIGNED_MODULE 13
472 473
473extern const char hex_asc[]; 474extern const char hex_asc[];
474#define hex_asc_lo(x) hex_asc[((x) & 0x0f)] 475#define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
diff --git a/include/trace/events/module.h b/include/trace/events/module.h
index 161932737416..11fd51b413de 100644
--- a/include/trace/events/module.h
+++ b/include/trace/events/module.h
@@ -22,8 +22,10 @@ struct module;
22 22
23#define show_module_flags(flags) __print_flags(flags, "", \ 23#define show_module_flags(flags) __print_flags(flags, "", \
24 { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ 24 { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \
25 { (1UL << TAINT_OOT_MODULE), "O" }, \
25 { (1UL << TAINT_FORCED_MODULE), "F" }, \ 26 { (1UL << TAINT_FORCED_MODULE), "F" }, \
26 { (1UL << TAINT_CRAP), "C" }) 27 { (1UL << TAINT_CRAP), "C" }, \
28 { (1UL << TAINT_UNSIGNED_MODULE), "X" })
27 29
28TRACE_EVENT(module_load, 30TRACE_EVENT(module_load,
29 31
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;