diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 6 | ||||
-rw-r--r-- | include/linux/module.h | 8 | ||||
-rw-r--r-- | init/Kconfig | 14 | ||||
-rw-r--r-- | kernel/Makefile | 1 | ||||
-rw-r--r-- | kernel/module-internal.h | 13 | ||||
-rw-r--r-- | kernel/module.c | 93 | ||||
-rw-r--r-- | kernel/module_signing.c | 23 |
7 files changed, 157 insertions, 1 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index ad7e2e5088c1..9b2b8d3ae3e0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1582,6 +1582,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1582 | log everything. Information is printed at KERN_DEBUG | 1582 | log everything. Information is printed at KERN_DEBUG |
1583 | so loglevel=8 may also need to be specified. | 1583 | so loglevel=8 may also need to be specified. |
1584 | 1584 | ||
1585 | module.sig_enforce | ||
1586 | [KNL] When CONFIG_MODULE_SIG is set, this means that | ||
1587 | modules without (valid) signatures will fail to load. | ||
1588 | Note that if CONFIG_MODULE_SIG_ENFORCE is set, that | ||
1589 | is always true, so this option does nothing. | ||
1590 | |||
1585 | mousedev.tap_time= | 1591 | mousedev.tap_time= |
1586 | [MOUSE] Maximum time between finger touching and | 1592 | [MOUSE] Maximum time between finger touching and |
1587 | leaving touchpad surface for touch to be considered | 1593 | leaving touchpad surface for touch to be considered |
diff --git a/include/linux/module.h b/include/linux/module.h index fbcafe2ee13e..7760c6d344a3 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -21,6 +21,9 @@ | |||
21 | #include <linux/percpu.h> | 21 | #include <linux/percpu.h> |
22 | #include <asm/module.h> | 22 | #include <asm/module.h> |
23 | 23 | ||
24 | /* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */ | ||
25 | #define MODULE_SIG_STRING "~Module signature appended~\n" | ||
26 | |||
24 | /* Not Yet Implemented */ | 27 | /* Not Yet Implemented */ |
25 | #define MODULE_SUPPORTED_DEVICE(name) | 28 | #define MODULE_SUPPORTED_DEVICE(name) |
26 | 29 | ||
@@ -260,6 +263,11 @@ struct module | |||
260 | const unsigned long *unused_gpl_crcs; | 263 | const unsigned long *unused_gpl_crcs; |
261 | #endif | 264 | #endif |
262 | 265 | ||
266 | #ifdef CONFIG_MODULE_SIG | ||
267 | /* Signature was verified. */ | ||
268 | bool sig_ok; | ||
269 | #endif | ||
270 | |||
263 | /* symbols that will be GPL-only in the near future. */ | 271 | /* symbols that will be GPL-only in the near future. */ |
264 | const struct kernel_symbol *gpl_future_syms; | 272 | const struct kernel_symbol *gpl_future_syms; |
265 | const unsigned long *gpl_future_crcs; | 273 | const unsigned long *gpl_future_crcs; |
diff --git a/init/Kconfig b/init/Kconfig index 66cc885abbc6..fa8ccad1ea43 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1585,6 +1585,20 @@ config MODULE_SRCVERSION_ALL | |||
1585 | the version). With this option, such a "srcversion" field | 1585 | the version). With this option, such a "srcversion" field |
1586 | will be created for all modules. If unsure, say N. | 1586 | will be created for all modules. If unsure, say N. |
1587 | 1587 | ||
1588 | config MODULE_SIG | ||
1589 | bool "Module signature verification" | ||
1590 | depends on MODULES | ||
1591 | help | ||
1592 | Check modules for valid signatures upon load: the signature | ||
1593 | is simply appended to the module. For more information see | ||
1594 | Documentation/module-signing.txt. | ||
1595 | |||
1596 | config MODULE_SIG_FORCE | ||
1597 | bool "Require modules to be validly signed" | ||
1598 | depends on MODULE_SIG | ||
1599 | help | ||
1600 | Reject unsigned modules or signed modules for which we don't have a | ||
1601 | key. Without this, such modules will simply taint the kernel. | ||
1588 | endif # MODULES | 1602 | endif # MODULES |
1589 | 1603 | ||
1590 | config INIT_ALL_POSSIBLE | 1604 | config INIT_ALL_POSSIBLE |
diff --git a/kernel/Makefile b/kernel/Makefile index c0cc67ad764c..08ba8a6abd1c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -55,6 +55,7 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o | |||
55 | obj-$(CONFIG_PROVE_LOCKING) += spinlock.o | 55 | obj-$(CONFIG_PROVE_LOCKING) += spinlock.o |
56 | obj-$(CONFIG_UID16) += uid16.o | 56 | obj-$(CONFIG_UID16) += uid16.o |
57 | obj-$(CONFIG_MODULES) += module.o | 57 | obj-$(CONFIG_MODULES) += module.o |
58 | obj-$(CONFIG_MODULE_SIG) += module_signing.o | ||
58 | obj-$(CONFIG_KALLSYMS) += kallsyms.o | 59 | obj-$(CONFIG_KALLSYMS) += kallsyms.o |
59 | obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o | 60 | obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o |
60 | obj-$(CONFIG_KEXEC) += kexec.o | 61 | obj-$(CONFIG_KEXEC) += kexec.o |
diff --git a/kernel/module-internal.h b/kernel/module-internal.h new file mode 100644 index 000000000000..033c17fd70ef --- /dev/null +++ b/kernel/module-internal.h | |||
@@ -0,0 +1,13 @@ | |||
1 | /* Module internals | ||
2 | * | ||
3 | * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | extern int mod_verify_sig(const void *mod, unsigned long modlen, | ||
13 | const void *sig, unsigned long siglen); | ||
diff --git a/kernel/module.c b/kernel/module.c index 74bc19562ca3..68c564edb2c1 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/jump_label.h> | 58 | #include <linux/jump_label.h> |
59 | #include <linux/pfn.h> | 59 | #include <linux/pfn.h> |
60 | #include <linux/bsearch.h> | 60 | #include <linux/bsearch.h> |
61 | #include "module-internal.h" | ||
61 | 62 | ||
62 | #define CREATE_TRACE_POINTS | 63 | #define CREATE_TRACE_POINTS |
63 | #include <trace/events/module.h> | 64 | #include <trace/events/module.h> |
@@ -102,6 +103,43 @@ static LIST_HEAD(modules); | |||
102 | struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ | 103 | struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ |
103 | #endif /* CONFIG_KGDB_KDB */ | 104 | #endif /* CONFIG_KGDB_KDB */ |
104 | 105 | ||
106 | #ifdef CONFIG_MODULE_SIG | ||
107 | #ifdef CONFIG_MODULE_SIG_FORCE | ||
108 | static bool sig_enforce = true; | ||
109 | #else | ||
110 | static bool sig_enforce = false; | ||
111 | |||
112 | static int param_set_bool_enable_only(const char *val, | ||
113 | const struct kernel_param *kp) | ||
114 | { | ||
115 | int err; | ||
116 | bool test; | ||
117 | struct kernel_param dummy_kp = *kp; | ||
118 | |||
119 | dummy_kp.arg = &test; | ||
120 | |||
121 | err = param_set_bool(val, &dummy_kp); | ||
122 | if (err) | ||
123 | return err; | ||
124 | |||
125 | /* Don't let them unset it once it's set! */ | ||
126 | if (!test && sig_enforce) | ||
127 | return -EROFS; | ||
128 | |||
129 | if (test) | ||
130 | sig_enforce = true; | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static const struct kernel_param_ops param_ops_bool_enable_only = { | ||
135 | .set = param_set_bool_enable_only, | ||
136 | .get = param_get_bool, | ||
137 | }; | ||
138 | #define param_check_bool_enable_only param_check_bool | ||
139 | |||
140 | module_param(sig_enforce, bool_enable_only, 0644); | ||
141 | #endif /* !CONFIG_MODULE_SIG_FORCE */ | ||
142 | #endif /* CONFIG_MODULE_SIG */ | ||
105 | 143 | ||
106 | /* Block module loading/unloading? */ | 144 | /* Block module loading/unloading? */ |
107 | int modules_disabled = 0; | 145 | int modules_disabled = 0; |
@@ -136,6 +174,7 @@ struct load_info { | |||
136 | unsigned long symoffs, stroffs; | 174 | unsigned long symoffs, stroffs; |
137 | struct _ddebug *debug; | 175 | struct _ddebug *debug; |
138 | unsigned int num_debug; | 176 | unsigned int num_debug; |
177 | bool sig_ok; | ||
139 | struct { | 178 | struct { |
140 | unsigned int sym, str, mod, vers, info, pcpu; | 179 | unsigned int sym, str, mod, vers, info, pcpu; |
141 | } index; | 180 | } index; |
@@ -2379,7 +2418,49 @@ static inline void kmemleak_load_module(const struct module *mod, | |||
2379 | } | 2418 | } |
2380 | #endif | 2419 | #endif |
2381 | 2420 | ||
2382 | /* Sets info->hdr and info->len. */ | 2421 | #ifdef CONFIG_MODULE_SIG |
2422 | static int module_sig_check(struct load_info *info, | ||
2423 | const void *mod, unsigned long *len) | ||
2424 | { | ||
2425 | int err = -ENOKEY; | ||
2426 | const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; | ||
2427 | const void *p = mod, *end = mod + *len; | ||
2428 | |||
2429 | /* Poor man's memmem. */ | ||
2430 | while ((p = memchr(p, MODULE_SIG_STRING[0], end - p))) { | ||
2431 | if (p + markerlen > end) | ||
2432 | break; | ||
2433 | |||
2434 | if (memcmp(p, MODULE_SIG_STRING, markerlen) == 0) { | ||
2435 | const void *sig = p + markerlen; | ||
2436 | /* Truncate module up to signature. */ | ||
2437 | *len = p - mod; | ||
2438 | err = mod_verify_sig(mod, *len, sig, end - sig); | ||
2439 | break; | ||
2440 | } | ||
2441 | p++; | ||
2442 | } | ||
2443 | |||
2444 | if (!err) { | ||
2445 | info->sig_ok = true; | ||
2446 | return 0; | ||
2447 | } | ||
2448 | |||
2449 | /* Not having a signature is only an error if we're strict. */ | ||
2450 | if (err == -ENOKEY && !sig_enforce) | ||
2451 | err = 0; | ||
2452 | |||
2453 | return err; | ||
2454 | } | ||
2455 | #else /* !CONFIG_MODULE_SIG */ | ||
2456 | static int module_sig_check(struct load_info *info, | ||
2457 | void *mod, unsigned long *len) | ||
2458 | { | ||
2459 | return 0; | ||
2460 | } | ||
2461 | #endif /* !CONFIG_MODULE_SIG */ | ||
2462 | |||
2463 | /* Sets info->hdr, info->len and info->sig_ok. */ | ||
2383 | static int copy_and_check(struct load_info *info, | 2464 | static int copy_and_check(struct load_info *info, |
2384 | const void __user *umod, unsigned long len, | 2465 | const void __user *umod, unsigned long len, |
2385 | const char __user *uargs) | 2466 | const char __user *uargs) |
@@ -2399,6 +2480,10 @@ static int copy_and_check(struct load_info *info, | |||
2399 | goto free_hdr; | 2480 | goto free_hdr; |
2400 | } | 2481 | } |
2401 | 2482 | ||
2483 | err = module_sig_check(info, hdr, &len); | ||
2484 | if (err) | ||
2485 | goto free_hdr; | ||
2486 | |||
2402 | /* Sanity checks against insmoding binaries or wrong arch, | 2487 | /* Sanity checks against insmoding binaries or wrong arch, |
2403 | weird elf version */ | 2488 | weird elf version */ |
2404 | if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 | 2489 | if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 |
@@ -2884,6 +2969,12 @@ static struct module *load_module(void __user *umod, | |||
2884 | goto free_copy; | 2969 | goto free_copy; |
2885 | } | 2970 | } |
2886 | 2971 | ||
2972 | #ifdef CONFIG_MODULE_SIG | ||
2973 | mod->sig_ok = info.sig_ok; | ||
2974 | if (!mod->sig_ok) | ||
2975 | add_taint_module(mod, TAINT_FORCED_MODULE); | ||
2976 | #endif | ||
2977 | |||
2887 | /* Now module is in final location, initialize linked lists, etc. */ | 2978 | /* Now module is in final location, initialize linked lists, etc. */ |
2888 | err = module_unload_init(mod); | 2979 | err = module_unload_init(mod); |
2889 | if (err) | 2980 | if (err) |
diff --git a/kernel/module_signing.c b/kernel/module_signing.c new file mode 100644 index 000000000000..499728aecafb --- /dev/null +++ b/kernel/module_signing.c | |||
@@ -0,0 +1,23 @@ | |||
1 | /* Module signature checker | ||
2 | * | ||
3 | * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/err.h> | ||
14 | #include "module-internal.h" | ||
15 | |||
16 | /* | ||
17 | * Verify the signature on a module. | ||
18 | */ | ||
19 | int mod_verify_sig(const void *mod, unsigned long modlen, | ||
20 | const void *sig, unsigned long siglen) | ||
21 | { | ||
22 | return -ENOKEY; | ||
23 | } | ||