This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / kernel / module-verify.c
1 /* module-verify.c: description
2  *
3  * Written by David Howells (dhowells@redhat.com)
4  * - Derived from GregKH's RSA module signer
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #include <linux/config.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/mm.h>
17 #include <linux/vmalloc.h>
18 #include <linux/elf.h>
19 #include <linux/crypto.h>
20 #include <linux/crypto/ksign.h>
21 #include <asm/scatterlist.h>
22 #include "module-verify.h"
23
24 #if 0
25 #define _debug(FMT, ...) printk(KERN_DEBUG FMT, ##__VA_ARGS__)
26 #else
27 #define _debug(FMT, ...) do { ; } while (0)
28 #endif
29
30 static int signedonly;
31
32 /*****************************************************************************/
33 /*
34  * verify the signature attached to a module
35  */
36 int module_verify_sig(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, const char *secstrings, struct module *mod)
37 {
38         struct crypto_tfm *sha1_tfm;
39         unsigned sig_index, sig_size;
40         char *sig;
41         int i;
42
43         /* pull the signature out of the file */
44         sig_index = 0;
45         for (i = 1; i < hdr->e_shnum; i++) {
46                 if (strcmp(secstrings + sechdrs[i].sh_name,
47                            "module_sig") == 0) {
48                         sig_index = i;
49                         break;
50                 }
51         }
52
53         if (sig_index <= 0)
54                 goto no_signature;
55
56         _debug("sig in section %d (size %d)\n",
57                sig_index, sechdrs[sig_index].sh_size);
58
59         sig = (char *) sechdrs[sig_index].sh_addr;
60         sig_size = sechdrs[sig_index].sh_size;
61
62         _debug("");
63
64
65
66
67         /* grab an SHA1 transformation context
68          * - !!! if this tries to load the sha1.ko module, we will deadlock!!!
69          */
70         sha1_tfm = crypto_alloc_tfm2("sha1", 0, 1);
71         if (!sha1_tfm) {
72                 printk("Couldn't load module - SHA1 transform unavailable\n");
73                 return -EPERM;
74         }
75
76         crypto_digest_init(sha1_tfm);
77
78         for (i = 1; i < hdr->e_shnum; i++) {
79                 uint8_t *data;
80                 int size;
81                 const char *name = secstrings + sechdrs[i].sh_name;
82
83                 /* We only care about sections with "text" or "data" in their names */
84                 if ((strstr(name, "text") == NULL) &&
85                     (strstr(name, "data") == NULL))
86                         continue;
87
88                 /* avoid the ".rel.*" sections too. */
89                 if (strstr(name, ".rel.") != NULL)
90                         continue;
91
92                 /* avoid the ".rel.*" sections too. */
93                 if (strstr(name, ".rela.") != NULL)
94                         continue;
95
96                 data = (uint8_t *) sechdrs[i].sh_addr;
97                 size = sechdrs[i].sh_size;
98
99                 _debug("SHA1ing the %s section, size %d\n", name, size);
100                 _debug("idata [ %02x%02x%02x%02x ]\n",
101                        data[0], data[1], data[2], data[3]);
102
103                 crypto_digest_update_kernel(sha1_tfm, data, size);
104         }
105
106         /* do the actual signature verification */
107         i = ksign_verify_signature(sig, sig_size, sha1_tfm);
108         if (!i)
109                 mod->gpgsig_ok = 1;
110         
111         return i;
112
113         /* deal with the case of an unsigned module */
114  no_signature:
115         if (!signedonly)
116                 return 0;
117         printk("An attempt to load unsigned module was rejected\n");
118         return -EPERM;
119 } /* end module_verify_sig() */
120
121 static int __init sign_setup(char *str)
122 {
123         signedonly = 1;
124         return 0;
125 }
126 __setup("enforcemodulesig", sign_setup);
127