]>
Commit | Line | Data |
---|---|---|
52cb69e7 AM |
1 | 2005-06-14 Jakub Jelinek <jakub@redhat.com> |
2 | ||
3 | * elf.c (bfd_elf_get_str_section): Allocate an extra byte after | |
4 | the end of strtab and clear it. | |
5 | (elf_read): Remove. | |
6 | ||
7 | * elf.c (bfd_section_from_shdr): Fail if name is NULL. | |
8 | Prevent endless recursion on broken objects. | |
9 | ||
10 | * archive.c (do_slurp_coff_armap): Check for overflows. | |
11 | ||
12 | 2005-05-26 Jakub Jelinek <jakub@redhat.com> | |
13 | ||
14 | * elfcode.h (elf_object_p): Fail if e_shoff != 0, e_shnum == 0 and | |
15 | first shdr has sh_size == 0. Fail if e_shnum is large to cause | |
16 | arithmetic overflow when allocating the i_shdr array. | |
17 | Sanity check sh_link and sh_info fields. Fix e_shstrndx sanity check. | |
18 | ||
19 | 2005-05-18 H.J. Lu <hongjiu.lu@intel.com> | |
20 | ||
21 | * elf.c (group_signature): Check if the symbol table section is | |
22 | correct. | |
23 | ||
24 | 2005-05-17 Tavis Ormandy <taviso@gentoo.org> | |
25 | ||
26 | * elf.c (bfd_section_from_shdr): Add sanity check when parsing | |
27 | dynamic sections. | |
28 | ||
29 | 2005-05-09 Alan Modra <amodra@bigpond.net.au> | |
30 | ||
31 | * elfcode.h (elf_object_p): Add more sanity checks on elf header. | |
32 | ||
33 | --- bfd/elf.c.jj 2005-02-07 14:42:44.000000000 -0500 | |
34 | +++ bfd/elf.c 2005-06-10 19:22:09.000000000 -0400 | |
35 | @@ -206,28 +206,6 @@ bfd_elf_hash (const char *namearg) | |
36 | return h & 0xffffffff; | |
37 | } | |
38 | ||
39 | -/* Read a specified number of bytes at a specified offset in an ELF | |
40 | - file, into a newly allocated buffer, and return a pointer to the | |
41 | - buffer. */ | |
42 | - | |
43 | -static char * | |
44 | -elf_read (bfd *abfd, file_ptr offset, bfd_size_type size) | |
45 | -{ | |
46 | - char *buf; | |
47 | - | |
48 | - if ((buf = bfd_alloc (abfd, size)) == NULL) | |
49 | - return NULL; | |
50 | - if (bfd_seek (abfd, offset, SEEK_SET) != 0) | |
51 | - return NULL; | |
52 | - if (bfd_bread (buf, size, abfd) != size) | |
53 | - { | |
54 | - if (bfd_get_error () != bfd_error_system_call) | |
55 | - bfd_set_error (bfd_error_file_truncated); | |
56 | - return NULL; | |
57 | - } | |
58 | - return buf; | |
59 | -} | |
60 | - | |
61 | bfd_boolean | |
62 | bfd_elf_mkobject (bfd *abfd) | |
63 | { | |
64 | @@ -267,7 +245,21 @@ bfd_elf_get_str_section (bfd *abfd, unsi | |
65 | /* No cached one, attempt to read, and cache what we read. */ | |
66 | offset = i_shdrp[shindex]->sh_offset; | |
67 | shstrtabsize = i_shdrp[shindex]->sh_size; | |
68 | - shstrtab = elf_read (abfd, offset, shstrtabsize); | |
69 | + | |
70 | + /* Allocate and clear an extra byte at the end, to prevent crashes | |
71 | + in case the string table is not terminated. */ | |
72 | + if (shstrtabsize + 1 == 0 | |
73 | + || (shstrtab = bfd_alloc (abfd, shstrtabsize + 1)) == NULL | |
74 | + || bfd_seek (abfd, offset, SEEK_SET) != 0) | |
75 | + shstrtab = NULL; | |
76 | + else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize) | |
77 | + { | |
78 | + if (bfd_get_error () != bfd_error_system_call) | |
79 | + bfd_set_error (bfd_error_file_truncated); | |
80 | + shstrtab = NULL; | |
81 | + } | |
82 | + else | |
83 | + shstrtab[shstrtabsize] = '\0'; | |
84 | i_shdrp[shindex]->contents = shstrtab; | |
85 | } | |
86 | return shstrtab; | |
87 | @@ -443,8 +435,11 @@ group_signature (bfd *abfd, Elf_Internal | |
88 | Elf_External_Sym_Shndx eshndx; | |
89 | Elf_Internal_Sym isym; | |
90 | ||
91 | - /* First we need to ensure the symbol table is available. */ | |
92 | - if (! bfd_section_from_shdr (abfd, ghdr->sh_link)) | |
93 | + /* First we need to ensure the symbol table is available. Make sure | |
94 | + that it is a symbol table section. */ | |
95 | + hdr = elf_elfsections (abfd) [ghdr->sh_link]; | |
96 | + if (hdr->sh_type != SHT_SYMTAB | |
97 | + || ! bfd_section_from_shdr (abfd, ghdr->sh_link)) | |
98 | return NULL; | |
99 | ||
100 | /* Go read the symbol. */ | |
101 | @@ -1735,6 +1730,8 @@ bfd_section_from_shdr (bfd *abfd, unsign | |
102 | name = bfd_elf_string_from_elf_section (abfd, | |
103 | elf_elfheader (abfd)->e_shstrndx, | |
104 | hdr->sh_name); | |
105 | + if (name == NULL) | |
106 | + return FALSE; | |
107 | ||
108 | switch (hdr->sh_type) | |
109 | { | |
110 | @@ -1755,6 +1752,9 @@ bfd_section_from_shdr (bfd *abfd, unsign | |
111 | case SHT_DYNAMIC: /* Dynamic linking information. */ | |
112 | if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) | |
113 | return FALSE; | |
114 | + if (hdr->sh_link > elf_numsections (abfd) | |
115 | + || elf_elfsections (abfd)[hdr->sh_link] == NULL) | |
116 | + return FALSE; | |
117 | if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB) | |
118 | { | |
119 | Elf_Internal_Shdr *dynsymhdr; | |
120 | @@ -1900,6 +1900,9 @@ bfd_section_from_shdr (bfd *abfd, unsign | |
121 | Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; | |
122 | if (hdr2->sh_link == shindex) | |
123 | { | |
124 | + /* Prevent endless recursion on broken objects. */ | |
125 | + if (i == shindex) | |
126 | + return FALSE; | |
127 | if (! bfd_section_from_shdr (abfd, i)) | |
128 | return FALSE; | |
129 | if (elf_onesymtab (abfd) == i) | |
130 | @@ -1975,6 +1978,10 @@ bfd_section_from_shdr (bfd *abfd, unsign | |
131 | if (hdr->sh_link != elf_onesymtab (abfd) || hdr->sh_info == SHN_UNDEF) | |
132 | return _bfd_elf_make_section_from_shdr (abfd, hdr, name); | |
133 | ||
134 | + /* Prevent endless recursion on broken objects. */ | |
135 | + if (elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL | |
136 | + || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA) | |
137 | + return FALSE; | |
138 | if (! bfd_section_from_shdr (abfd, hdr->sh_info)) | |
139 | return FALSE; | |
140 | target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info); | |
141 | --- bfd/elfcode.h.jj 2005-02-07 14:42:44.000000000 -0500 | |
142 | +++ bfd/elfcode.h 2005-05-25 13:09:21.000000000 -0400 | |
143 | @@ -33,7 +33,7 @@ Foundation, Inc., 59 Temple Place - Suit | |
144 | /* Problems and other issues to resolve. | |
145 | ||
146 | (1) BFD expects there to be some fixed number of "sections" in | |
147 | - the object file. I.E. there is a "section_count" variable in the | |
148 | + the object file. I.E. there is a "section_count" variable in the | |
149 | bfd structure which contains the number of sections. However, ELF | |
150 | supports multiple "views" of a file. In particular, with current | |
151 | implementations, executable files typically have two tables, a | |
152 | @@ -612,8 +612,13 @@ elf_object_p (bfd *abfd) | |
153 | ||
154 | if (i_ehdrp->e_shoff != 0) | |
155 | { | |
156 | + bfd_signed_vma where = i_ehdrp->e_shoff; | |
157 | + | |
158 | + if (where != (file_ptr) where) | |
159 | + goto got_wrong_format_error; | |
160 | + | |
161 | /* Seek to the section header table in the file. */ | |
162 | - if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0) | |
163 | + if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) | |
164 | goto got_no_match; | |
165 | ||
166 | /* Read the first section header at index 0, and convert to internal | |
167 | @@ -625,11 +630,46 @@ elf_object_p (bfd *abfd) | |
168 | /* If the section count is zero, the actual count is in the first | |
169 | section header. */ | |
170 | if (i_ehdrp->e_shnum == SHN_UNDEF) | |
171 | - i_ehdrp->e_shnum = i_shdr.sh_size; | |
172 | + { | |
173 | + i_ehdrp->e_shnum = i_shdr.sh_size; | |
174 | + if (i_ehdrp->e_shnum != i_shdr.sh_size | |
175 | + || i_ehdrp->e_shnum == 0) | |
176 | + goto got_wrong_format_error; | |
177 | + } | |
178 | ||
179 | /* And similarly for the string table index. */ | |
180 | if (i_ehdrp->e_shstrndx == SHN_XINDEX) | |
181 | - i_ehdrp->e_shstrndx = i_shdr.sh_link; | |
182 | + { | |
183 | + i_ehdrp->e_shstrndx = i_shdr.sh_link; | |
184 | + if (i_ehdrp->e_shstrndx != i_shdr.sh_link) | |
185 | + goto got_wrong_format_error; | |
186 | + } | |
187 | + | |
188 | + /* Sanity check that we can read all of the section headers. | |
189 | + It ought to be good enough to just read the last one. */ | |
190 | + if (i_ehdrp->e_shnum != 1) | |
191 | + { | |
192 | + /* Check that we don't have a totally silly number of sections. */ | |
193 | + if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr) | |
194 | + || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr)) | |
195 | + goto got_wrong_format_error; | |
196 | + | |
197 | + where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr); | |
198 | + if (where != (file_ptr) where) | |
199 | + goto got_wrong_format_error; | |
200 | + if ((bfd_size_type) where <= i_ehdrp->e_shoff) | |
201 | + goto got_wrong_format_error; | |
202 | + | |
203 | + if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) | |
204 | + goto got_no_match; | |
205 | + if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) | |
206 | + goto got_no_match; | |
207 | + | |
208 | + /* Back to where we were. */ | |
209 | + where = i_ehdrp->e_shoff + sizeof (x_shdr); | |
210 | + if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) | |
211 | + goto got_no_match; | |
212 | + } | |
213 | } | |
214 | ||
215 | /* Allocate space for a copy of the section header table in | |
216 | @@ -673,6 +713,20 @@ elf_object_p (bfd *abfd) | |
217 | goto got_no_match; | |
218 | elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); | |
219 | ||
220 | + /* Sanity check sh_link and sh_info. */ | |
221 | + if (i_shdrp[shindex].sh_link >= num_sec | |
222 | + || (i_shdrp[shindex].sh_link >= SHN_LORESERVE | |
223 | + && i_shdrp[shindex].sh_link <= SHN_HIRESERVE)) | |
224 | + goto got_wrong_format_error; | |
225 | + | |
226 | + if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK) | |
227 | + || i_shdrp[shindex].sh_type == SHT_RELA | |
228 | + || i_shdrp[shindex].sh_type == SHT_REL) | |
229 | + && (i_shdrp[shindex].sh_info >= num_sec | |
230 | + || (i_shdrp[shindex].sh_info >= SHN_LORESERVE | |
231 | + && i_shdrp[shindex].sh_info <= SHN_HIRESERVE))) | |
232 | + goto got_wrong_format_error; | |
233 | + | |
234 | /* If the section is loaded, but not page aligned, clear | |
235 | D_PAGED. */ | |
236 | if (i_shdrp[shindex].sh_size != 0 | |
237 | @@ -685,6 +739,17 @@ elf_object_p (bfd *abfd) | |
238 | } | |
239 | } | |
240 | ||
241 | + /* A further sanity check. */ | |
242 | + if (i_ehdrp->e_shnum != 0) | |
243 | + { | |
244 | + if (i_ehdrp->e_shstrndx >= elf_numsections (abfd) | |
245 | + || (i_ehdrp->e_shstrndx >= SHN_LORESERVE | |
246 | + && i_ehdrp->e_shstrndx <= SHN_HIRESERVE)) | |
247 | + goto got_wrong_format_error; | |
248 | + } | |
249 | + else if (i_ehdrp->e_shstrndx != 0) | |
250 | + goto got_wrong_format_error; | |
251 | + | |
252 | /* Read in the program headers. */ | |
253 | if (i_ehdrp->e_phnum == 0) | |
254 | elf_tdata (abfd)->phdr = NULL; | |
255 | @@ -1042,7 +1107,7 @@ elf_slurp_symbol_table (bfd *abfd, asymb | |
256 | symcount); | |
257 | ||
258 | /* Slurp in the symbols without the version information, | |
259 | - since that is more helpful than just quitting. */ | |
260 | + since that is more helpful than just quitting. */ | |
261 | verhdr = NULL; | |
262 | } | |
263 | ||
264 | @@ -1107,7 +1172,7 @@ elf_slurp_symbol_table (bfd *abfd, asymb | |
265 | sym->symbol.section = bfd_abs_section_ptr; | |
266 | ||
267 | /* If this is a relocatable file, then the symbol value is | |
268 | - already section relative. */ | |
269 | + already section relative. */ | |
270 | if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) | |
271 | sym->symbol.value -= sym->symbol.section->vma; | |
272 | ||
273 | --- bfd/archive.c.jj 2005-06-10 19:02:01.000000000 +0200 | |
274 | +++ bfd/archive.c 2005-06-10 19:50:21.000000000 +0200 | |
275 | @@ -821,9 +821,15 @@ do_slurp_coff_armap (bfd *abfd) | |
276 | /* The coff armap must be read sequentially. So we construct a | |
277 | bsd-style one in core all at once, for simplicity. */ | |
278 | ||
279 | + if (nsymz > ~ (bfd_size_type) 0 / sizeof (carsym)) | |
280 | + return FALSE; | |
281 | + | |
282 | carsym_size = (nsymz * sizeof (carsym)); | |
283 | ptrsize = (4 * nsymz); | |
284 | ||
285 | + if (carsym_size + stringsize + 1 <= carsym_size) | |
286 | + return FALSE; | |
287 | + | |
288 | ardata->symdefs = bfd_zalloc (abfd, carsym_size + stringsize + 1); | |
289 | if (ardata->symdefs == NULL) | |
290 | return FALSE; |