Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / kernel / module-verify.c
1 /* module-verify.c: module verifier
2  *
3  * Written by David Howells (dhowells@redhat.com)
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version
8  * 2 of the License, or (at your option) any later version.
9  */
10
11 #include <linux/config.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/elf.h>
16 #include <linux/crypto.h>
17 #include <linux/crypto/ksign.h>
18 #include "module-verify.h"
19
20 #if 0
21 #define _debug(FMT, ...) printk(FMT, ##__VA_ARGS__)
22 #else
23 #define _debug(FMT, ...) do {} while (0)
24 #endif
25
26 static int module_verify_elf(struct module_verify_data *mvdata);
27
28 /*****************************************************************************/
29 /*
30  * verify a module's integrity
31  * - check the ELF is viable
32  * - check the module's signature if it has one
33  */
34 int module_verify(const Elf_Ehdr *hdr, size_t size)
35 {
36         struct module_verify_data mvdata;
37         int ret;
38
39         memset(&mvdata, 0, sizeof(mvdata));
40         mvdata.buffer   = hdr;
41         mvdata.hdr      = hdr;
42         mvdata.size     = size;
43
44         ret = module_verify_elf(&mvdata);
45         if (ret < 0) {
46                 if (ret == -ELIBBAD)
47                         printk("Module failed ELF checks\n");
48                 goto error;
49         }
50
51 #ifdef CONFIG_MODULE_SIG
52         ret = module_verify_signature(&mvdata);
53 #endif
54
55  error:
56         kfree(mvdata.secsizes);
57         kfree(mvdata.canonlist);
58         return ret;
59
60 } /* end module_verify() */
61
62 /*****************************************************************************/
63 /*
64  * verify the ELF structure of a module
65  */
66 static int module_verify_elf(struct module_verify_data *mvdata)
67 {
68         const Elf_Ehdr *hdr = mvdata->hdr;
69         const Elf_Shdr *section, *section2, *secstop;
70         const Elf_Rela *relas, *rela, *relastop;
71         const Elf_Rel *rels, *rel, *relstop;
72         const Elf_Sym *symbol, *symstop;
73         size_t size, sssize, *secsize, tmp, tmp2;
74         long last;
75         int line;
76
77         size = mvdata->size;
78         mvdata->nsects = hdr->e_shnum;
79
80 #define elfcheck(X) \
81 do { if (unlikely(!(X))) { line = __LINE__; goto elfcheck_error; } } while(0)
82
83 #define seccheck(X) \
84 do { if (unlikely(!(X))) { line = __LINE__; goto seccheck_error; } } while(0)
85
86 #define symcheck(X) \
87 do { if (unlikely(!(X))) { line = __LINE__; goto symcheck_error; } } while(0)
88
89 #define relcheck(X) \
90 do { if (unlikely(!(X))) { line = __LINE__; goto relcheck_error; } } while(0)
91
92 #define relacheck(X) \
93 do { if (unlikely(!(X))) { line = __LINE__; goto relacheck_error; } } while(0)
94
95         /* validate the ELF header */
96         elfcheck(hdr->e_ehsize < size);
97         elfcheck(hdr->e_entry == 0);
98         elfcheck(hdr->e_phoff == 0);
99         elfcheck(hdr->e_phnum == 0);
100
101         elfcheck(hdr->e_shnum < SHN_LORESERVE);
102         elfcheck(hdr->e_shoff < size);
103         elfcheck(hdr->e_shoff >= hdr->e_ehsize);
104         elfcheck((hdr->e_shoff & (sizeof(long) - 1)) == 0);
105         elfcheck(hdr->e_shstrndx > 0);
106         elfcheck(hdr->e_shstrndx < hdr->e_shnum);
107         elfcheck(hdr->e_shentsize == sizeof(Elf_Shdr));
108
109         tmp = (size_t) hdr->e_shentsize * (size_t) hdr->e_shnum;
110         elfcheck(tmp <= size - hdr->e_shoff);
111
112         /* allocate a table to hold in-file section sizes */
113         mvdata->secsizes = kmalloc(hdr->e_shnum * sizeof(size_t), GFP_KERNEL);
114         if (!mvdata->secsizes)
115                 return -ENOMEM;
116
117         memset(mvdata->secsizes, 0, hdr->e_shnum * sizeof(size_t));
118
119         /* validate the ELF section headers */
120         mvdata->sections = mvdata->buffer + hdr->e_shoff;
121         secstop = mvdata->sections + mvdata->nsects;
122
123         sssize = mvdata->sections[hdr->e_shstrndx].sh_size;
124         elfcheck(sssize > 0);
125
126         section = mvdata->sections;
127         seccheck(section->sh_type == SHT_NULL);
128         seccheck(section->sh_size == 0);
129         seccheck(section->sh_offset == 0);
130
131         secsize = mvdata->secsizes + 1;
132         for (section++; section < secstop; secsize++, section++) {
133                 seccheck(section->sh_name < sssize);
134                 seccheck(section->sh_link < hdr->e_shnum);
135
136                 if (section->sh_entsize > 0)
137                         seccheck(section->sh_size % section->sh_entsize == 0);
138
139                 seccheck(section->sh_offset >= hdr->e_ehsize);
140                 seccheck(section->sh_offset < size);
141
142                 /* determine the section's in-file size */
143                 tmp = size - section->sh_offset;
144                 if (section->sh_offset < hdr->e_shoff)
145                         tmp = hdr->e_shoff - section->sh_offset;
146
147                 for (section2 = mvdata->sections + 1; section2 < secstop; section2++) {
148                         if (section->sh_offset < section2->sh_offset) {
149                                 tmp2 = section2->sh_offset - section->sh_offset;
150                                 if (tmp2 < tmp)
151                                         tmp = tmp2;
152                         }
153                 }
154                 *secsize = tmp;
155
156                 _debug("Section %ld: %zx bytes at %lx\n",
157                        section - mvdata->sections,
158                        *secsize,
159                        section->sh_offset);
160
161                 /* perform section type specific checks */
162                 switch (section->sh_type) {
163                 case SHT_NOBITS:
164                         break;
165
166                 case SHT_REL:
167                         seccheck(section->sh_entsize == sizeof(Elf_Rel));
168                         goto more_rel_checks;
169
170                 case SHT_RELA:
171                         seccheck(section->sh_entsize == sizeof(Elf_Rela));
172                 more_rel_checks:
173                         seccheck(section->sh_info > 0);
174                         seccheck(section->sh_info < hdr->e_shnum);
175                         goto more_sec_checks;
176
177                 case SHT_SYMTAB:
178                         seccheck(section->sh_entsize == sizeof(Elf_Sym));
179                         goto more_sec_checks;
180
181                 default:
182                 more_sec_checks:
183                         /* most types of section must be contained entirely
184                          * within the file */
185                         seccheck(section->sh_size <= *secsize);
186                         break;
187                 }
188         }
189
190         /* validate the ELF section names */
191         section = &mvdata->sections[hdr->e_shstrndx];
192
193         seccheck(section->sh_offset != hdr->e_shoff);
194
195         mvdata->secstrings = mvdata->buffer + section->sh_offset;
196
197         last = -1;
198         for (section = mvdata->sections + 1; section < secstop; section++) {
199                 const char *secname;
200                 tmp = sssize - section->sh_name;
201                 secname = mvdata->secstrings + section->sh_name;
202                 seccheck(secname[0] != 0);
203                 if (section->sh_name > last)
204                         last = section->sh_name;
205         }
206
207         if (last > -1) {
208                 tmp = sssize - last;
209                 elfcheck(memchr(mvdata->secstrings + last, 0, tmp) != NULL);
210         }
211
212         /* look for various sections in the module */
213         for (section = mvdata->sections + 1; section < secstop; section++) {
214                 switch (section->sh_type) {
215                 case SHT_SYMTAB:
216                         if (strcmp(mvdata->secstrings + section->sh_name,
217                                    ".symtab") == 0
218                             ) {
219                                 seccheck(mvdata->symbols == NULL);
220                                 mvdata->symbols =
221                                         mvdata->buffer + section->sh_offset;
222                                 mvdata->nsyms =
223                                         section->sh_size / sizeof(Elf_Sym);
224                                 seccheck(section->sh_size > 0);
225                         }
226                         break;
227
228                 case SHT_STRTAB:
229                         if (strcmp(mvdata->secstrings + section->sh_name,
230                                    ".strtab") == 0
231                             ) {
232                                 seccheck(mvdata->strings == NULL);
233                                 mvdata->strings =
234                                         mvdata->buffer + section->sh_offset;
235                                 sssize = mvdata->nstrings = section->sh_size;
236                                 seccheck(section->sh_size > 0);
237                         }
238                         break;
239                 }
240         }
241
242         if (!mvdata->symbols) {
243                 printk("Couldn't locate module symbol table\n");
244                 goto format_error;
245         }
246
247         if (!mvdata->strings) {
248                 printk("Couldn't locate module strings table\n");
249                 goto format_error;
250         }
251
252         /* validate the symbol table */
253         symstop = mvdata->symbols + mvdata->nsyms;
254
255         symbol = mvdata->symbols;
256         symcheck(ELF_ST_TYPE(symbol[0].st_info) == STT_NOTYPE);
257         symcheck(symbol[0].st_shndx == SHN_UNDEF);
258         symcheck(symbol[0].st_value == 0);
259         symcheck(symbol[0].st_size == 0);
260
261         last = -1;
262         for (symbol++; symbol < symstop; symbol++) {
263                 symcheck(symbol->st_name < sssize);
264                 if (symbol->st_name > last)
265                         last = symbol->st_name;
266                 symcheck(symbol->st_shndx < mvdata->nsects ||
267                          symbol->st_shndx >= SHN_LORESERVE);
268         }
269
270         if (last > -1) {
271                 tmp = sssize - last;
272                 elfcheck(memchr(mvdata->strings + last, 0, tmp) != NULL);
273         }
274
275         /* validate each relocation table as best we can */
276         for (section = mvdata->sections + 1; section < secstop; section++) {
277                 section2 = mvdata->sections + section->sh_info;
278
279                 switch (section->sh_type) {
280                 case SHT_REL:
281                         rels = mvdata->buffer + section->sh_offset;
282                         relstop = mvdata->buffer + section->sh_offset + section->sh_size;
283
284                         for (rel = rels; rel < relstop; rel++) {
285                                 relcheck(rel->r_offset < section2->sh_size);
286                                 relcheck(ELF_R_SYM(rel->r_info) < mvdata->nsyms);
287                         }
288
289                         break;
290
291                 case SHT_RELA:
292                         relas = mvdata->buffer + section->sh_offset;
293                         relastop = mvdata->buffer + section->sh_offset + section->sh_size;
294
295                         for (rela = relas; rela < relastop; rela++) {
296                                 relacheck(rela->r_offset < section2->sh_size);
297                                 relacheck(ELF_R_SYM(rela->r_info) < mvdata->nsyms);
298                         }
299
300                         break;
301
302                 default:
303                         break;
304                 }
305         }
306
307
308         _debug("ELF okay\n");
309         return 0;
310
311  elfcheck_error:
312         printk("Verify ELF error (assertion %d)\n", line);
313         goto format_error;
314
315  seccheck_error:
316         printk("Verify ELF error [sec %ld] (assertion %d)\n",
317                (long)(section - mvdata->sections), line);
318         goto format_error;
319
320  symcheck_error:
321         printk("Verify ELF error [sym %ld] (assertion %d)\n",
322                (long)(symbol - mvdata->symbols), line);
323         goto format_error;
324
325  relcheck_error:
326         printk("Verify ELF error [sec %ld rel %ld] (assertion %d)\n",
327                (long)(section - mvdata->sections),
328                (long)(rel - rels), line);
329         goto format_error;
330
331  relacheck_error:
332         printk("Verify ELF error [sec %ld rela %ld] (assertion %d)\n",
333                (long)(section - mvdata->sections),
334                (long)(rela - relas), line);
335         goto format_error;
336
337  format_error:
338         return -ELIBBAD;
339
340 } /* end module_verify_elf() */