1 /* module-verify-sig.c: module signature checker
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 * - Derived from GregKH's RSA module signer
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/elf.h>
17 #include <linux/crypto.h>
18 #include <linux/crypto/ksign.h>
19 #include "module-verify.h"
24 #define _debug(FMT, ...) printk(FMT, ##__VA_ARGS__)
26 #define _debug(FMT, ...) do {} while (0)
30 #define count_and_csum(C, __p,__n) \
33 for (__loop = 0; __loop < __n; __loop++) { \
34 (C)->csum += __p[__loop]; \
35 (C)->xcsum += __p[__loop]; \
37 (C)->signed_size += __n; \
40 #define count_and_csum(C, __p,__n) \
42 (C)->signed_size += __n; \
46 #define crypto_digest_update_data(C,PTR,N) \
49 uint8_t *__p = (uint8_t *)(PTR); \
50 count_and_csum((C), __p, __n); \
51 crypto_digest_update_kernel((C)->digest, __p, __n); \
54 #define crypto_digest_update_val(C,VAL) \
56 size_t __n = sizeof(VAL); \
57 uint8_t *__p = (uint8_t *)&(VAL); \
58 count_and_csum((C), __p, __n); \
59 crypto_digest_update_kernel((C)->digest, __p, __n); \
62 static int module_verify_canonicalise(struct module_verify_data *mvdata);
64 static int extract_elf_rela(struct module_verify_data *mvdata,
66 const Elf_Rela *relatab, size_t nrels,
69 static int extract_elf_rel(struct module_verify_data *mvdata,
71 const Elf_Rel *reltab, size_t nrels,
74 static int signedonly;
76 /*****************************************************************************/
78 * verify a module's signature
80 int module_verify_signature(struct module_verify_data *mvdata)
82 const Elf_Shdr *sechdrs = mvdata->sections;
83 const char *secstrings = mvdata->secstrings;
88 for (i = 1; i < mvdata->nsects; i++) {
89 switch (sechdrs[i].sh_type) {
91 if (strcmp(mvdata->secstrings + sechdrs[i].sh_name,
92 ".module_sig") == 0) {
93 mvdata->sig_index = i;
99 if (mvdata->sig_index <= 0)
102 sig = mvdata->buffer + sechdrs[mvdata->sig_index].sh_offset;
103 sig_size = sechdrs[mvdata->sig_index].sh_size;
105 _debug("sig in section %d (size %d)\n",
106 mvdata->sig_index, sig_size);
108 /* produce a canonicalisation map for the sections */
109 ret = module_verify_canonicalise(mvdata);
113 /* grab an SHA1 transformation context
114 * - !!! if this tries to load the sha1.ko module, we will deadlock!!!
116 mvdata->digest = crypto_alloc_tfm2("sha1", 0, 1);
117 if (!mvdata->digest) {
118 printk("Couldn't load module - SHA1 transform unavailable\n");
122 crypto_digest_init(mvdata->digest);
128 /* load data from each relevant section into the digest */
129 for (i = 1; i < mvdata->nsects; i++) {
130 unsigned long sh_type = sechdrs[i].sh_type;
131 unsigned long sh_info = sechdrs[i].sh_info;
132 unsigned long sh_size = sechdrs[i].sh_size;
133 unsigned long sh_flags = sechdrs[i].sh_flags;
134 const char *sh_name = secstrings + sechdrs[i].sh_name;
135 const void *data = mvdata->buffer + sechdrs[i].sh_offset;
137 if (i == mvdata->sig_index)
144 /* it would be nice to include relocation sections, but the act
145 * of adding a signature to the module seems changes their
146 * contents, because the symtab gets changed when sections are
147 * added or removed */
148 if (sh_type == SHT_REL || sh_type == SHT_RELA) {
149 if (mvdata->canonlist[sh_info]) {
150 uint32_t xsh_info = mvdata->canonmap[sh_info];
152 crypto_digest_update_data(mvdata, sh_name, strlen(sh_name));
153 crypto_digest_update_val(mvdata, sechdrs[i].sh_type);
154 crypto_digest_update_val(mvdata, sechdrs[i].sh_flags);
155 crypto_digest_update_val(mvdata, sechdrs[i].sh_size);
156 crypto_digest_update_val(mvdata, sechdrs[i].sh_addralign);
157 crypto_digest_update_val(mvdata, xsh_info);
159 if (sh_type == SHT_RELA)
160 ret = extract_elf_rela(
163 sh_size / sizeof(Elf_Rela),
166 ret = extract_elf_rel(
169 sh_size / sizeof(Elf_Rel),
179 /* include allocatable loadable sections */
180 if (sh_type != SHT_NOBITS && sh_flags & SHF_ALLOC)
181 goto include_section;
186 crypto_digest_update_data(mvdata, sh_name, strlen(sh_name));
187 crypto_digest_update_val(mvdata, sechdrs[i].sh_type);
188 crypto_digest_update_val(mvdata, sechdrs[i].sh_flags);
189 crypto_digest_update_val(mvdata, sechdrs[i].sh_size);
190 crypto_digest_update_val(mvdata, sechdrs[i].sh_addralign);
191 crypto_digest_update_data(mvdata, data, sh_size);
193 _debug("%08zx %02x digested the %s section, size %ld\n",
194 mvdata->signed_size, mvdata->csum, sh_name, sh_size);
196 mvdata->canonlist[i] = 1;
199 _debug("Contributed %zu bytes to the digest (csum 0x%02x)\n",
200 mvdata->signed_size, mvdata->xcsum);
202 /* do the actual signature verification */
203 i = ksign_verify_signature(sig, sig_size, mvdata->digest);
205 _debug("verify-sig : %d\n", i);
212 crypto_free_tfm(mvdata->digest);
215 /* deal with the case of an unsigned module */
219 printk("An attempt to load unsigned module was rejected\n");
222 } /* end module_verify_signature() */
224 /*****************************************************************************/
226 * canonicalise the section table index numbers
228 static int module_verify_canonicalise(struct module_verify_data *mvdata)
230 int canon, loop, changed, tmp;
232 /* produce a list of index numbers of sections that contribute
233 * to the kernel's module image
236 kmalloc(sizeof(int) * mvdata->nsects * 2, GFP_KERNEL);
237 if (!mvdata->canonlist)
240 mvdata->canonmap = mvdata->canonlist + mvdata->nsects;
243 for (loop = 1; loop < mvdata->nsects; loop++) {
244 const Elf_Shdr *section = mvdata->sections + loop;
246 if (loop != mvdata->sig_index) {
247 /* we only need to canonicalise allocatable sections */
248 if (section->sh_flags & SHF_ALLOC)
249 mvdata->canonlist[canon++] = loop;
253 /* canonicalise the index numbers of the contributing section */
257 for (loop = 0; loop < canon - 1; loop++) {
260 x = mvdata->secstrings +
261 mvdata->sections[mvdata->canonlist[loop + 0]].sh_name;
262 y = mvdata->secstrings +
263 mvdata->sections[mvdata->canonlist[loop + 1]].sh_name;
265 if (strcmp(x, y) > 0) {
266 tmp = mvdata->canonlist[loop + 0];
267 mvdata->canonlist[loop + 0] =
268 mvdata->canonlist[loop + 1];
269 mvdata->canonlist[loop + 1] = tmp;
276 for (loop = 0; loop < canon; loop++)
277 mvdata->canonmap[mvdata->canonlist[loop]] = loop + 1;
281 } /* end module_verify_canonicalise() */
283 /*****************************************************************************/
285 * extract a RELA table
286 * - need to canonicalise the entries in case section addition/removal has
287 * rearranged the symbol table and the section table
289 static int extract_elf_rela(struct module_verify_data *mvdata,
291 const Elf_Rela *relatab, size_t nrels,
295 #if defined(MODULES_ARE_ELF32)
304 #elif defined(MODULES_ARE_ELF64)
314 #error unsupported module type
316 } __attribute__((packed)) relocation;
318 const Elf_Rela *reloc;
319 const Elf_Sym *symbol;
322 /* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
323 for (loop = 0; loop < nrels; loop++) {
326 reloc = &relatab[loop];
328 /* decode the relocation */
329 relocation.r_offset = reloc->r_offset;
330 relocation.r_addend = reloc->r_addend;
331 relocation.r_type = ELF_R_TYPE(reloc->r_info);
333 /* decode the symbol referenced by the relocation */
334 symbol = &mvdata->symbols[ELF_R_SYM(reloc->r_info)];
335 relocation.st_info = symbol->st_info;
336 relocation.st_other = symbol->st_other;
337 relocation.st_value = symbol->st_value;
338 relocation.st_size = symbol->st_size;
339 relocation.st_shndx = symbol->st_shndx;
340 st_shndx = symbol->st_shndx;
342 /* canonicalise the section used by the symbol */
343 if (st_shndx > SHN_UNDEF && st_shndx < mvdata->nsects)
344 relocation.st_shndx = mvdata->canonmap[st_shndx];
346 crypto_digest_update_val(mvdata, relocation);
348 /* undefined symbols must be named if referenced */
349 if (st_shndx == SHN_UNDEF) {
350 const char *name = mvdata->strings + symbol->st_name;
351 crypto_digest_update_data(mvdata,
352 name, strlen(name) + 1);
356 _debug("%08zx %02x digested the %s section, nrels %zu\n",
357 mvdata->signed_size, mvdata->csum, sh_name, nrels);
360 } /* end extract_elf_rela() */
362 /*****************************************************************************/
366 static int extract_elf_rel(struct module_verify_data *mvdata,
368 const Elf_Rel *reltab, size_t nrels,
372 #if defined(MODULES_ARE_ELF32)
380 #elif defined(MODULES_ARE_ELF64)
389 #error unsupported module type
391 } __attribute__((packed)) relocation;
393 const Elf_Rel *reloc;
394 const Elf_Sym *symbol;
397 /* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
398 for (loop = 0; loop < nrels; loop++) {
401 reloc = &reltab[loop];
403 /* decode the relocation */
404 relocation.r_offset = reloc->r_offset;
405 relocation.r_type = ELF_R_TYPE(reloc->r_info);
407 /* decode the symbol referenced by the relocation */
408 symbol = &mvdata->symbols[ELF_R_SYM(reloc->r_info)];
409 relocation.st_info = symbol->st_info;
410 relocation.st_other = symbol->st_other;
411 relocation.st_value = symbol->st_value;
412 relocation.st_size = symbol->st_size;
413 relocation.st_shndx = symbol->st_shndx;
414 st_shndx = symbol->st_shndx;
416 /* canonicalise the section used by the symbol */
417 if (st_shndx > SHN_UNDEF && st_shndx < mvdata->nsects)
418 relocation.st_shndx = mvdata->canonmap[st_shndx];
420 crypto_digest_update_val(mvdata, relocation);
422 /* undefined symbols must be named if referenced */
423 if (st_shndx == SHN_UNDEF) {
424 const char *name = mvdata->strings + symbol->st_name;
425 crypto_digest_update_data(mvdata,
426 name, strlen(name) + 1);
430 _debug("%08zx %02x digested the %s section, nrels %zu\n",
431 mvdata->signed_size, mvdata->csum, sh_name, nrels);
434 } /* end extract_elf_rel() */
436 static int __init sign_setup(char *str)
441 __setup("enforcemodulesig", sign_setup);