aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--include/linux/module.h8
-rw-r--r--init/Kconfig14
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/module-internal.h13
-rw-r--r--kernel/module.c93
-rw-r--r--kernel/module_signing.c23
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
1588config 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
1596config 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.
1588endif # MODULES 1602endif # MODULES
1589 1603
1590config INIT_ALL_POSSIBLE 1604config 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
55obj-$(CONFIG_PROVE_LOCKING) += spinlock.o 55obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
56obj-$(CONFIG_UID16) += uid16.o 56obj-$(CONFIG_UID16) += uid16.o
57obj-$(CONFIG_MODULES) += module.o 57obj-$(CONFIG_MODULES) += module.o
58obj-$(CONFIG_MODULE_SIG) += module_signing.o
58obj-$(CONFIG_KALLSYMS) += kallsyms.o 59obj-$(CONFIG_KALLSYMS) += kallsyms.o
59obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o 60obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
60obj-$(CONFIG_KEXEC) += kexec.o 61obj-$(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
12extern 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);
102struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ 103struct 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
108static bool sig_enforce = true;
109#else
110static bool sig_enforce = false;
111
112static 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
134static 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
140module_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? */
107int modules_disabled = 0; 145int 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
2422static 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 */
2456static 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. */
2383static int copy_and_check(struct load_info *info, 2464static 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 */
19int mod_verify_sig(const void *mod, unsigned long modlen,
20 const void *sig, unsigned long siglen)
21{
22 return -ENOKEY;
23}