1 |
commit: 4609f57a690b4a5670baeb93167dab5300d07d4e |
2 |
Author: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Feb 1 19:29:10 2017 +0000 |
4 |
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Feb 1 19:29:10 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=4609f57a |
7 |
|
8 |
dumpelf: check for invalid section entry sizes |
9 |
|
10 |
URL: https://bugs.gentoo.org/607894 |
11 |
Reported-by: Agostino Sarubbo <ago <AT> gentoo.org> |
12 |
|
13 |
dumpelf.c | 50 ++++++++++++++++++++++++++++---------------------- |
14 |
1 file changed, 28 insertions(+), 22 deletions(-) |
15 |
|
16 |
diff --git a/dumpelf.c b/dumpelf.c |
17 |
index 6b2458a..44da3ee 100644 |
18 |
--- a/dumpelf.c |
19 |
+++ b/dumpelf.c |
20 |
@@ -413,17 +413,20 @@ static void dump_shdr(elfobj *elf, const void *shdr_void, size_t shdr_cnt, const |
21 |
case SHT_DYNSYM: { \ |
22 |
Elf##B##_Sym *sym = vdata; \ |
23 |
printf("\n\t/%c section dump:\n", '*'); \ |
24 |
- for (i = 0; i < EGET(shdr->sh_size) / EGET(shdr->sh_entsize); ++i) { \ |
25 |
- printf("\t * Elf%i_Sym sym%zu = {\n", B, i); \ |
26 |
- printf("\t * \t.st_name = %u,\n", (uint32_t)EGET(sym->st_name)); \ |
27 |
- printf("\t * \t.st_value = 0x%"PRIX64",\n", EGET(sym->st_value)); \ |
28 |
- printf("\t * \t.st_size = %"PRIu64", (bytes)\n", EGET(sym->st_size)); \ |
29 |
- printf("\t * \t.st_info = %u,\n", (unsigned char)EGET(sym->st_info)); \ |
30 |
- printf("\t * \t.st_other = %u,\n", (unsigned char)EGET(sym->st_other)); \ |
31 |
- printf("\t * \t.st_shndx = %u\n", (uint16_t)EGET(sym->st_shndx)); \ |
32 |
- printf("\t * };\n"); \ |
33 |
- ++sym; \ |
34 |
- } \ |
35 |
+ if (EGET(shdr->sh_entsize) < sizeof(*sym)) \ |
36 |
+ printf(" /* corrupt section ! */ "); \ |
37 |
+ else \ |
38 |
+ for (i = 0; i < EGET(shdr->sh_size) / EGET(shdr->sh_entsize); ++i) { \ |
39 |
+ printf("\t * Elf%i_Sym sym%zu = {\n", B, i); \ |
40 |
+ printf("\t * \t.st_name = %u,\n", (uint32_t)EGET(sym->st_name)); \ |
41 |
+ printf("\t * \t.st_value = 0x%"PRIX64",\n", EGET(sym->st_value)); \ |
42 |
+ printf("\t * \t.st_size = %"PRIu64", (bytes)\n", EGET(sym->st_size)); \ |
43 |
+ printf("\t * \t.st_info = %u,\n", (unsigned char)EGET(sym->st_info)); \ |
44 |
+ printf("\t * \t.st_other = %u,\n", (unsigned char)EGET(sym->st_other)); \ |
45 |
+ printf("\t * \t.st_shndx = %u\n", (uint16_t)EGET(sym->st_shndx)); \ |
46 |
+ printf("\t * };\n"); \ |
47 |
+ ++sym; \ |
48 |
+ } \ |
49 |
printf("\t */\n"); \ |
50 |
break; \ |
51 |
} \ |
52 |
@@ -433,17 +436,20 @@ static void dump_shdr(elfobj *elf, const void *shdr_void, size_t shdr_cnt, const |
53 |
case SHT_GNU_LIBLIST: { \ |
54 |
Elf##B##_Lib *lib = vdata; \ |
55 |
printf("\n\t/%c section dump:\n", '*'); \ |
56 |
- for (i = 0; i < EGET(shdr->sh_size) / EGET(shdr->sh_entsize); ++i) { \ |
57 |
- printf("\t * Elf%i_Lib lib%zu = {\n", B, i); \ |
58 |
- printf("\t * \t.l_name = %"PRIu64",\n", EGET(lib->l_name)); \ |
59 |
- printf("\t * \t.l_time_stamp = 0x%"PRIX64", (%s)\n", \ |
60 |
- EGET(lib->l_time_stamp), timestamp(EGET(lib->l_time_stamp))); \ |
61 |
- printf("\t * \t.l_checksum = 0x%"PRIX64",\n", EGET(lib->l_checksum)); \ |
62 |
- printf("\t * \t.l_version = %"PRIu64",\n", EGET(lib->l_version)); \ |
63 |
- printf("\t * \t.l_flags = 0x%"PRIX64"\n", EGET(lib->l_flags)); \ |
64 |
- printf("\t * };\n"); \ |
65 |
- ++lib; \ |
66 |
- } \ |
67 |
+ if (EGET(shdr->sh_entsize) < sizeof(*lib)) \ |
68 |
+ printf(" /* corrupt section ! */ "); \ |
69 |
+ else \ |
70 |
+ for (i = 0; i < EGET(shdr->sh_size) / EGET(shdr->sh_entsize); ++i) { \ |
71 |
+ printf("\t * Elf%i_Lib lib%zu = {\n", B, i); \ |
72 |
+ printf("\t * \t.l_name = %"PRIu64",\n", EGET(lib->l_name)); \ |
73 |
+ printf("\t * \t.l_time_stamp = 0x%"PRIX64", (%s)\n", \ |
74 |
+ EGET(lib->l_time_stamp), timestamp(EGET(lib->l_time_stamp))); \ |
75 |
+ printf("\t * \t.l_checksum = 0x%"PRIX64",\n", EGET(lib->l_checksum)); \ |
76 |
+ printf("\t * \t.l_version = %"PRIu64",\n", EGET(lib->l_version)); \ |
77 |
+ printf("\t * \t.l_flags = 0x%"PRIX64"\n", EGET(lib->l_flags)); \ |
78 |
+ printf("\t * };\n"); \ |
79 |
+ ++lib; \ |
80 |
+ } \ |
81 |
printf("\t */\n"); \ |
82 |
} \ |
83 |
default: { \ |