diff options
Diffstat (limited to 'scripts/mod')
-rw-r--r-- | scripts/mod/modpost.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 65bdfdb56877..1912c752e422 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -333,10 +333,10 @@ void release_file(void *file, unsigned long size) | |||
333 | munmap(file, size); | 333 | munmap(file, size); |
334 | } | 334 | } |
335 | 335 | ||
336 | static void parse_elf(struct elf_info *info, const char *filename) | 336 | static int parse_elf(struct elf_info *info, const char *filename) |
337 | { | 337 | { |
338 | unsigned int i; | 338 | unsigned int i; |
339 | Elf_Ehdr *hdr = info->hdr; | 339 | Elf_Ehdr *hdr; |
340 | Elf_Shdr *sechdrs; | 340 | Elf_Shdr *sechdrs; |
341 | Elf_Sym *sym; | 341 | Elf_Sym *sym; |
342 | 342 | ||
@@ -346,9 +346,18 @@ static void parse_elf(struct elf_info *info, const char *filename) | |||
346 | exit(1); | 346 | exit(1); |
347 | } | 347 | } |
348 | info->hdr = hdr; | 348 | info->hdr = hdr; |
349 | if (info->size < sizeof(*hdr)) | 349 | if (info->size < sizeof(*hdr)) { |
350 | goto truncated; | 350 | /* file too small, assume this is an empty .o file */ |
351 | 351 | return 0; | |
352 | } | ||
353 | /* Is this a valid ELF file? */ | ||
354 | if ((hdr->e_ident[EI_MAG0] != ELFMAG0) || | ||
355 | (hdr->e_ident[EI_MAG1] != ELFMAG1) || | ||
356 | (hdr->e_ident[EI_MAG2] != ELFMAG2) || | ||
357 | (hdr->e_ident[EI_MAG3] != ELFMAG3)) { | ||
358 | /* Not an ELF file - silently ignore it */ | ||
359 | return 0; | ||
360 | } | ||
352 | /* Fix endianness in ELF header */ | 361 | /* Fix endianness in ELF header */ |
353 | hdr->e_shoff = TO_NATIVE(hdr->e_shoff); | 362 | hdr->e_shoff = TO_NATIVE(hdr->e_shoff); |
354 | hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); | 363 | hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); |
@@ -371,8 +380,10 @@ static void parse_elf(struct elf_info *info, const char *filename) | |||
371 | = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | 380 | = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; |
372 | const char *secname; | 381 | const char *secname; |
373 | 382 | ||
374 | if (sechdrs[i].sh_offset > info->size) | 383 | if (sechdrs[i].sh_offset > info->size) { |
375 | goto truncated; | 384 | fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr)); |
385 | return 0; | ||
386 | } | ||
376 | secname = secstrings + sechdrs[i].sh_name; | 387 | secname = secstrings + sechdrs[i].sh_name; |
377 | if (strcmp(secname, ".modinfo") == 0) { | 388 | if (strcmp(secname, ".modinfo") == 0) { |
378 | info->modinfo = (void *)hdr + sechdrs[i].sh_offset; | 389 | info->modinfo = (void *)hdr + sechdrs[i].sh_offset; |
@@ -407,10 +418,7 @@ static void parse_elf(struct elf_info *info, const char *filename) | |||
407 | sym->st_value = TO_NATIVE(sym->st_value); | 418 | sym->st_value = TO_NATIVE(sym->st_value); |
408 | sym->st_size = TO_NATIVE(sym->st_size); | 419 | sym->st_size = TO_NATIVE(sym->st_size); |
409 | } | 420 | } |
410 | return; | 421 | return 1; |
411 | |||
412 | truncated: | ||
413 | fatal("%s is truncated.\n", filename); | ||
414 | } | 422 | } |
415 | 423 | ||
416 | static void parse_elf_finish(struct elf_info *info) | 424 | static void parse_elf_finish(struct elf_info *info) |
@@ -1089,7 +1097,8 @@ static void read_symbols(char *modname) | |||
1089 | struct elf_info info = { }; | 1097 | struct elf_info info = { }; |
1090 | Elf_Sym *sym; | 1098 | Elf_Sym *sym; |
1091 | 1099 | ||
1092 | parse_elf(&info, modname); | 1100 | if (!parse_elf(&info, modname)) |
1101 | return; | ||
1093 | 1102 | ||
1094 | mod = new_module(modname); | 1103 | mod = new_module(modname); |
1095 | 1104 | ||