aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2012-10-19 20:19:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-19 20:30:40 -0400
commitcaabe240574aec05b2f5667414ce80f9075c2ba1 (patch)
treed92bf96b009bd0b0caec44c21348812b06805909 /kernel/module.c
parentb6bb324dbddd704b4b9a85971e1f7ae79abb2e1d (diff)
MODSIGN: Move the magic string to the end of a module and eliminate the search
Emit the magic string that indicates a module has a signature after the signature data instead of before it. This allows module_sig_check() to be made simpler and faster by the elimination of the search for the magic string. Instead we just need to do a single memcmp(). This works because at the end of the signature data there is the fixed-length signature information block. This block then falls immediately prior to the magic number. From the contents of the information block, it is trivial to calculate the size of the signature data and thus the size of the actual module data. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c26
1 files changed, 9 insertions, 17 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 0e2da8695f8e..6085f5ef88ea 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2421,25 +2421,17 @@ static inline void kmemleak_load_module(const struct module *mod,
2421 2421
2422#ifdef CONFIG_MODULE_SIG 2422#ifdef CONFIG_MODULE_SIG
2423static int module_sig_check(struct load_info *info, 2423static int module_sig_check(struct load_info *info,
2424 const void *mod, unsigned long *len) 2424 const void *mod, unsigned long *_len)
2425{ 2425{
2426 int err = -ENOKEY; 2426 int err = -ENOKEY;
2427 const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; 2427 unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
2428 const void *p = mod, *end = mod + *len; 2428 unsigned long len = *_len;
2429 2429
2430 /* Poor man's memmem. */ 2430 if (len > markerlen &&
2431 while ((p = memchr(p, MODULE_SIG_STRING[0], end - p))) { 2431 memcmp(mod + len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
2432 if (p + markerlen > end) 2432 /* We truncate the module to discard the signature */
2433 break; 2433 *_len -= markerlen;
2434 2434 err = mod_verify_sig(mod, _len);
2435 if (memcmp(p, MODULE_SIG_STRING, markerlen) == 0) {
2436 const void *sig = p + markerlen;
2437 /* Truncate module up to signature. */
2438 *len = p - mod;
2439 err = mod_verify_sig(mod, *len, sig, end - sig);
2440 break;
2441 }
2442 p++;
2443 } 2435 }
2444 2436
2445 if (!err) { 2437 if (!err) {