]>
Commit | Line | Data |
---|---|---|
0dcd74c7 JR |
1 | src/ |
2 | 2005-06-09 Roland McGrath <roland@redhat.com> | |
3 | ||
4 | * readelf.c (handle_dynamic, handle_symtab): Check for bogus sh_link. | |
5 | (handle_verneed, handle_verdef, handle_versym, handle_hash): Likewise. | |
6 | (handle_scngrp): Check for bogus sh_info. | |
7 | ||
8 | * strip.c (handle_elf): Check for bogus values in sh_link, sh_info, | |
9 | st_shndx, e_shstrndx, and SHT_GROUP or SHT_SYMTAB_SHNDX data. | |
10 | Don't use assert on input values, instead bail with "illformed" error. | |
11 | ||
12 | 2005-05-17 Jakub Jelinek <jakub@redhat.com> | |
13 | ||
14 | libelf/ | |
15 | * elf32_getphdr.c (elfw2(LIBELFBITS,getphdr)): Check if program header | |
16 | table fits into object's bounds. | |
17 | * elf_getshstrndx.c (elf_getshstrndx): Add elf->start_offset to | |
18 | elf->map_address. Check if first section header fits into object's | |
19 | bounds. | |
20 | * elf32_getshdr.c (elfw2(LIBELFBITS,getshdr)): Fix comment pasto. | |
21 | Check if section header table fits into object's bounds. | |
22 | * elf_begin.c (get_shnum): Fail if maxsize is smaller than ELF headers. | |
23 | Ensure first section header fits into object's bounds. | |
24 | (file_read_elf): Make sure scncnt is small enough to allocate both | |
25 | ElfXX_Shdr and Elf_Scn array. Make sure section and program header | |
26 | tables fit into object's bounds. Avoid memory leak on failure. | |
27 | ||
28 | src/ | |
29 | * elflint.c (check_hash): Don't check entries beyond end of section. | |
30 | (check_note): Don't crash if gelf_rawchunk fails. | |
31 | (section_name): Return <invalid> if gelf_getshdr returns NULL. | |
32 | ||
33 | 2005-05-14 Jakub Jelinek <jakub@redhat.com> | |
34 | ||
35 | libelf/ | |
36 | * libelfP.h (INVALID_NDX): Define. | |
37 | * gelf_getdyn.c (gelf_getdyn): Use it. Remove ndx < 0 test if any. | |
38 | * gelf_getlib.c (gelf_getlib): Likewise. | |
39 | * gelf_getmove.c (gelf_getmove): Likewise. | |
40 | * gelf_getrel.c (gelf_getrel): Likewise. | |
41 | * gelf_getrela.c (gelf_getrela): Likewise. | |
42 | * gelf_getsym.c (gelf_getsym): Likewise. | |
43 | * gelf_getsyminfo.c (gelf_getsyminfo): Likewise. | |
44 | * gelf_getsymshndx.c (gelf_getsymshndx): Likewise. | |
45 | * gelf_getversym.c (gelf_getversym): Likewise. | |
46 | * gelf_update_dyn.c (gelf_update_dyn): Likewise. | |
47 | * gelf_update_lib.c (gelf_update_lib): Likewise. | |
48 | * gelf_update_move.c (gelf_update_move): Likewise. | |
49 | * gelf_update_rel.c (gelf_update_rel): Likewise. | |
50 | * gelf_update_rela.c (gelf_update_rela): Likewise. | |
51 | * gelf_update_sym.c (gelf_update_sym): Likewise. | |
52 | * gelf_update_syminfo.c (gelf_update_syminfo): Likewise. | |
53 | * gelf_update_symshndx.c (gelf_update_symshndx): Likewise. | |
54 | * gelf_update_versym.c (gelf_update_versym): Likewise. | |
55 | * elf_newscn.c (elf_newscn): Check for overflow. | |
56 | * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Likewise. | |
57 | (__elfw2(LIBELFBITS,updatefile)): Likewise. | |
58 | * elf_begin.c (file_read_elf): Likewise. | |
59 | * elf32_newphdr.c (elfw2(LIBELFBITS,newphdr)): Likewise. | |
60 | * elf_getarsym.c (elf_getarsym): Likewise. | |
61 | * elf32_getshdr.c (elfw2(LIBELFBITS,getshdr)): Likewise. | |
62 | src/ | |
63 | * elflint.c (section_name): Return "<invalid>" instead of | |
64 | crashing on invalid section name. | |
65 | (check_symtab, is_rel_dyn, check_rela, check_rel, check_dynamic, | |
66 | check_symtab_shndx, check_hash, check_versym): Robustify. | |
67 | ||
68 | --- elfutils-0.108/libelf/gelf_getrel.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
69 | +++ elfutils-0.108/libelf/gelf_getrel.c 2005-05-14 01:31:25.000000000 +0200 | |
70 | @@ -1,5 +1,5 @@ | |
71 | /* Get REL relocation information at given index. | |
72 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
73 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
74 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
75 | ||
76 | This program is free software; you can redistribute it and/or modify | |
77 | @@ -38,12 +38,6 @@ gelf_getrel (data, ndx, dst) | |
78 | if (data_scn == NULL) | |
79 | return NULL; | |
80 | ||
81 | - if (unlikely (ndx < 0)) | |
82 | - { | |
83 | - __libelf_seterrno (ELF_E_INVALID_INDEX); | |
84 | - return NULL; | |
85 | - } | |
86 | - | |
87 | if (unlikely (data_scn->d.d_type != ELF_T_REL)) | |
88 | { | |
89 | __libelf_seterrno (ELF_E_INVALID_HANDLE); | |
90 | @@ -60,7 +54,8 @@ gelf_getrel (data, ndx, dst) | |
91 | if (scn->elf->class == ELFCLASS32) | |
92 | { | |
93 | /* We have to convert the data. */ | |
94 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size)) | |
95 | + if (INVALID_NDX (ndx, Elf32_Rel) | |
96 | + || unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size)) | |
97 | { | |
98 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
99 | result = NULL; | |
100 | @@ -80,7 +75,8 @@ gelf_getrel (data, ndx, dst) | |
101 | { | |
102 | /* Simply copy the data after we made sure we are actually getting | |
103 | correct data. */ | |
104 | - if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size)) | |
105 | + if (INVALID_NDX (ndx, Elf64_Rel) | |
106 | + || unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size)) | |
107 | { | |
108 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
109 | result = NULL; | |
110 | --- elfutils-0.108/libelf/gelf_getsym.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
111 | +++ elfutils-0.108/libelf/gelf_getsym.c 2005-05-14 01:31:25.000000000 +0200 | |
112 | @@ -1,5 +1,5 @@ | |
113 | /* Get symbol information from symbol table at the given index. | |
114 | - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. | |
115 | + Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc. | |
116 | Written by Ulrich Drepper <drepper@redhat.com>, 1999. | |
117 | ||
118 | This program is free software; you can redistribute it and/or modify | |
119 | @@ -57,7 +57,8 @@ gelf_getsym (data, ndx, dst) | |
120 | table entries has to be adopted. The user better has provided | |
121 | a buffer where we can store the information. While copying the | |
122 | data we are converting the format. */ | |
123 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size)) | |
124 | + if (INVALID_NDX (ndx, Elf32_Sym) | |
125 | + || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size)) | |
126 | { | |
127 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
128 | goto out; | |
129 | @@ -86,7 +87,8 @@ gelf_getsym (data, ndx, dst) | |
130 | ||
131 | /* The data is already in the correct form. Just make sure the | |
132 | index is OK. */ | |
133 | - if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size)) | |
134 | + if (INVALID_NDX (ndx, GElf_Sym) | |
135 | + || unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size)) | |
136 | { | |
137 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
138 | goto out; | |
139 | --- elfutils-0.108/libelf/gelf_update_sym.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
140 | +++ elfutils-0.108/libelf/gelf_update_sym.c 2005-05-14 01:31:25.000000000 +0200 | |
141 | @@ -1,5 +1,5 @@ | |
142 | /* Update symbol information in symbol table at the given index. | |
143 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
144 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
145 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
146 | ||
147 | This program is free software; you can redistribute it and/or modify | |
148 | @@ -39,12 +39,6 @@ gelf_update_sym (data, ndx, src) | |
149 | if (data == NULL) | |
150 | return 0; | |
151 | ||
152 | - if (unlikely (ndx < 0)) | |
153 | - { | |
154 | - __libelf_seterrno (ELF_E_INVALID_INDEX); | |
155 | - return 0; | |
156 | - } | |
157 | - | |
158 | if (unlikely (data_scn->d.d_type != ELF_T_SYM)) | |
159 | { | |
160 | /* The type of the data better should match. */ | |
161 | @@ -69,7 +63,8 @@ gelf_update_sym (data, ndx, src) | |
162 | } | |
163 | ||
164 | /* Check whether we have to resize the data buffer. */ | |
165 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size)) | |
166 | + if (INVALID_NDX (ndx, Elf32_Sym) | |
167 | + || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size)) | |
168 | { | |
169 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
170 | goto out; | |
171 | @@ -92,7 +87,8 @@ gelf_update_sym (data, ndx, src) | |
172 | else | |
173 | { | |
174 | /* Check whether we have to resize the data buffer. */ | |
175 | - if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size)) | |
176 | + if (INVALID_NDX (ndx, Elf64_Sym) | |
177 | + || unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size)) | |
178 | { | |
179 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
180 | goto out; | |
181 | --- elfutils-0.108/libelf/gelf_getrela.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
182 | +++ elfutils-0.108/libelf/gelf_getrela.c 2005-05-14 01:31:25.000000000 +0200 | |
183 | @@ -1,5 +1,5 @@ | |
184 | /* Get RELA relocation information at given index. | |
185 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
186 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
187 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
188 | ||
189 | This program is free software; you can redistribute it and/or modify | |
190 | @@ -38,12 +38,6 @@ gelf_getrela (data, ndx, dst) | |
191 | if (data_scn == NULL) | |
192 | return NULL; | |
193 | ||
194 | - if (unlikely (ndx < 0)) | |
195 | - { | |
196 | - __libelf_seterrno (ELF_E_INVALID_INDEX); | |
197 | - return NULL; | |
198 | - } | |
199 | - | |
200 | if (unlikely (data_scn->d.d_type != ELF_T_RELA)) | |
201 | { | |
202 | __libelf_seterrno (ELF_E_INVALID_HANDLE); | |
203 | @@ -60,7 +54,8 @@ gelf_getrela (data, ndx, dst) | |
204 | if (scn->elf->class == ELFCLASS32) | |
205 | { | |
206 | /* We have to convert the data. */ | |
207 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size)) | |
208 | + if (INVALID_NDX (ndx, Elf32_Rela) | |
209 | + || unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size)) | |
210 | { | |
211 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
212 | result = NULL; | |
213 | @@ -81,7 +76,8 @@ gelf_getrela (data, ndx, dst) | |
214 | { | |
215 | /* Simply copy the data after we made sure we are actually getting | |
216 | correct data. */ | |
217 | - if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size)) | |
218 | + if (INVALID_NDX (ndx, Elf64_Rela) | |
219 | + || unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size)) | |
220 | { | |
221 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
222 | result = NULL; | |
223 | --- elfutils-0.108/libelf/gelf_update_syminfo.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
224 | +++ elfutils-0.108/libelf/gelf_update_syminfo.c 2005-05-14 01:31:25.000000000 +0200 | |
225 | @@ -1,5 +1,5 @@ | |
226 | /* Update additional symbol information in symbol table at the given index. | |
227 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
228 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
229 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
230 | ||
231 | This program is free software; you can redistribute it and/or modify | |
232 | @@ -39,12 +39,6 @@ gelf_update_syminfo (data, ndx, src) | |
233 | if (data == NULL) | |
234 | return 0; | |
235 | ||
236 | - if (unlikely (ndx < 0)) | |
237 | - { | |
238 | - __libelf_seterrno (ELF_E_INVALID_INDEX); | |
239 | - return 0; | |
240 | - } | |
241 | - | |
242 | if (unlikely (data_scn->d.d_type != ELF_T_SYMINFO)) | |
243 | { | |
244 | /* The type of the data better should match. */ | |
245 | @@ -60,7 +54,8 @@ gelf_update_syminfo (data, ndx, src) | |
246 | rwlock_wrlock (scn->elf->lock); | |
247 | ||
248 | /* Check whether we have to resize the data buffer. */ | |
249 | - if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size)) | |
250 | + if (INVALID_NDX (ndx, GElf_Syminfo) | |
251 | + || unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size)) | |
252 | { | |
253 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
254 | goto out; | |
255 | --- elfutils-0.108/libelf/gelf_getsyminfo.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
256 | +++ elfutils-0.108/libelf/gelf_getsyminfo.c 2005-05-14 01:31:25.000000000 +0200 | |
257 | @@ -1,5 +1,5 @@ | |
258 | /* Get additional symbol information from symbol table at the given index. | |
259 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
260 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
261 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
262 | ||
263 | This program is free software; you can redistribute it and/or modify | |
264 | @@ -51,7 +51,8 @@ gelf_getsyminfo (data, ndx, dst) | |
265 | ||
266 | /* The data is already in the correct form. Just make sure the | |
267 | index is OK. */ | |
268 | - if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size)) | |
269 | + if (INVALID_NDX (ndx, GElf_Syminfo) | |
270 | + || unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size)) | |
271 | { | |
272 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
273 | goto out; | |
274 | --- elfutils-0.108/libelf/elf_newscn.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
275 | +++ elfutils-0.108/libelf/elf_newscn.c 2005-05-14 01:38:35.000000000 +0200 | |
276 | @@ -1,5 +1,5 @@ | |
277 | /* Append new section. | |
278 | - Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. | |
279 | + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc. | |
280 | Written by Ulrich Drepper <drepper@redhat.com>, 1998. | |
281 | ||
282 | This program is free software; you can redistribute it and/or modify | |
283 | @@ -71,13 +71,21 @@ elf_newscn (elf) | |
284 | else | |
285 | { | |
286 | /* We must allocate a new element. */ | |
287 | - Elf_ScnList *newp; | |
288 | + Elf_ScnList *newp = NULL; | |
289 | ||
290 | assert (elf->state.elf.scnincr > 0); | |
291 | ||
292 | - newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList) | |
293 | - + ((elf->state.elf.scnincr *= 2) | |
294 | - * sizeof (Elf_Scn)), 1); | |
295 | + if ( | |
296 | +#if SIZE_MAX <= 4294967295U | |
297 | + likely (elf->state.elf.scnincr | |
298 | + < SIZE_MAX / 2 / sizeof (Elf_Scn) - sizeof (Elf_ScnList)) | |
299 | +#else | |
300 | + 1 | |
301 | +#endif | |
302 | + ) | |
303 | + newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList) | |
304 | + + ((elf->state.elf.scnincr *= 2) | |
305 | + * sizeof (Elf_Scn)), 1); | |
306 | if (newp == NULL) | |
307 | { | |
308 | __libelf_seterrno (ELF_E_NOMEM); | |
309 | --- elfutils-0.108/libelf/gelf_update_lib.c.jj 2004-01-23 19:23:03.000000000 +0100 | |
310 | +++ elfutils-0.108/libelf/gelf_update_lib.c 2005-05-14 01:31:25.000000000 +0200 | |
311 | @@ -1,5 +1,5 @@ | |
312 | /* Update library in table at the given index. | |
313 | - Copyright (C) 2004 Red Hat, Inc. | |
314 | + Copyright (C) 2004, 2005 Red Hat, Inc. | |
315 | Written by Ulrich Drepper <drepper@redhat.com>, 2004. | |
316 | ||
317 | This program is free software; you can redistribute it and/or modify | |
318 | @@ -35,12 +35,6 @@ gelf_update_lib (data, ndx, src) | |
319 | if (data == NULL) | |
320 | return 0; | |
321 | ||
322 | - if (unlikely (ndx < 0)) | |
323 | - { | |
324 | - __libelf_seterrno (ELF_E_INVALID_INDEX); | |
325 | - return 0; | |
326 | - } | |
327 | - | |
328 | Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; | |
329 | if (unlikely (data_scn->d.d_type != ELF_T_LIB)) | |
330 | { | |
331 | @@ -54,7 +48,8 @@ gelf_update_lib (data, ndx, src) | |
332 | ||
333 | /* Check whether we have to resize the data buffer. */ | |
334 | int result = 0; | |
335 | - if (unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size)) | |
336 | + if (INVALID_NDX (ndx, Elf64_Lib) | |
337 | + || unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size)) | |
338 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
339 | else | |
340 | { | |
341 | --- elfutils-0.108/libelf/gelf_getmove.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
342 | +++ elfutils-0.108/libelf/gelf_getmove.c 2005-05-14 01:31:25.000000000 +0200 | |
343 | @@ -1,5 +1,5 @@ | |
344 | /* Get move structure at the given index. | |
345 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
346 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
347 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
348 | ||
349 | This program is free software; you can redistribute it and/or modify | |
350 | @@ -50,7 +50,8 @@ gelf_getmove (data, ndx, dst) | |
351 | ||
352 | /* The data is already in the correct form. Just make sure the | |
353 | index is OK. */ | |
354 | - if (unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size)) | |
355 | + if (INVALID_NDX (ndx, GElf_Move) | |
356 | + || unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size)) | |
357 | { | |
358 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
359 | goto out; | |
360 | --- elfutils-0.108/libelf/elf32_updatefile.c.jj 2005-02-06 10:14:52.000000000 +0100 | |
361 | +++ elfutils-0.108/libelf/elf32_updatefile.c 2005-05-14 00:45:03.000000000 +0200 | |
362 | @@ -164,6 +164,9 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf | |
363 | /* Write all the sections. Well, only those which are modified. */ | |
364 | if (shnum > 0) | |
365 | { | |
366 | + if (unlikely (shnum > SIZE_MAX / sizeof (Elf_Scn *))) | |
367 | + return 1; | |
368 | + | |
369 | ElfW2(LIBELFBITS,Shdr) *shdr_dest; | |
370 | Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns; | |
371 | Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *)); | |
372 | @@ -468,6 +471,10 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf | |
373 | /* Write all the sections. Well, only those which are modified. */ | |
374 | if (shnum > 0) | |
375 | { | |
376 | + if (unlikely (shnum > SIZE_MAX / (sizeof (Elf_Scn *) | |
377 | + + sizeof (ElfW2(LIBELFBITS,Shdr))))) | |
378 | + return 1; | |
379 | + | |
380 | off_t shdr_offset = elf->start_offset + ehdr->e_shoff; | |
381 | #if EV_NUM != 2 | |
382 | xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]; | |
383 | --- elfutils-0.108/libelf/gelf_getsymshndx.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
384 | +++ elfutils-0.108/libelf/gelf_getsymshndx.c 2005-05-14 01:31:25.000000000 +0200 | |
385 | @@ -1,6 +1,6 @@ | |
386 | /* Get symbol information and separate section index from symbol table | |
387 | at the given index. | |
388 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
389 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
390 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
391 | ||
392 | This program is free software; you can redistribute it and/or modify | |
393 | @@ -57,7 +57,9 @@ gelf_getsymshndx (symdata, shndxdata, nd | |
394 | section index table. */ | |
395 | if (likely (shndxdata_scn != NULL)) | |
396 | { | |
397 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size)) | |
398 | + if (INVALID_NDX (ndx, Elf32_Word) | |
399 | + || unlikely ((ndx + 1) * sizeof (Elf32_Word) | |
400 | + > shndxdata_scn->d.d_size)) | |
401 | { | |
402 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
403 | goto out; | |
404 | @@ -77,7 +79,8 @@ gelf_getsymshndx (symdata, shndxdata, nd | |
405 | table entries has to be adopted. The user better has provided | |
406 | a buffer where we can store the information. While copying the | |
407 | data we are converting the format. */ | |
408 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata->d_size)) | |
409 | + if (INVALID_NDX (ndx, Elf32_Sym) | |
410 | + || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata->d_size)) | |
411 | { | |
412 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
413 | goto out; | |
414 | @@ -106,7 +109,8 @@ gelf_getsymshndx (symdata, shndxdata, nd | |
415 | ||
416 | /* The data is already in the correct form. Just make sure the | |
417 | index is OK. */ | |
418 | - if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > symdata->d_size)) | |
419 | + if (INVALID_NDX (ndx, GElf_Sym) | |
420 | + || unlikely ((ndx + 1) * sizeof (GElf_Sym) > symdata->d_size)) | |
421 | { | |
422 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
423 | goto out; | |
424 | --- elfutils-0.108/libelf/gelf_update_move.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
425 | +++ elfutils-0.108/libelf/gelf_update_move.c 2005-05-14 01:31:25.000000000 +0200 | |
426 | @@ -1,5 +1,5 @@ | |
427 | /* Update move structure at the given index. | |
428 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
429 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
430 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
431 | ||
432 | This program is free software; you can redistribute it and/or modify | |
433 | @@ -42,7 +42,7 @@ gelf_update_move (data, ndx, src) | |
434 | assert (sizeof (GElf_Move) == sizeof (Elf64_Move)); | |
435 | ||
436 | /* Check whether we have to resize the data buffer. */ | |
437 | - if (unlikely (ndx < 0) | |
438 | + if (INVALID_NDX (ndx, GElf_Move) | |
439 | || unlikely ((ndx + 1) * sizeof (GElf_Move) > data_scn->d.d_size)) | |
440 | { | |
441 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
442 | --- elfutils-0.108/libelf/gelf_update_dyn.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
443 | +++ elfutils-0.108/libelf/gelf_update_dyn.c 2005-05-14 01:31:25.000000000 +0200 | |
444 | @@ -1,5 +1,5 @@ | |
445 | /* Update information in dynamic table at the given index. | |
446 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
447 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
448 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
449 | ||
450 | This program is free software; you can redistribute it and/or modify | |
451 | @@ -38,12 +38,6 @@ gelf_update_dyn (data, ndx, src) | |
452 | if (data == NULL) | |
453 | return 0; | |
454 | ||
455 | - if (unlikely (ndx < 0)) | |
456 | - { | |
457 | - __libelf_seterrno (ELF_E_INVALID_INDEX); | |
458 | - return 0; | |
459 | - } | |
460 | - | |
461 | if (unlikely (data_scn->d.d_type != ELF_T_DYN)) | |
462 | { | |
463 | /* The type of the data better should match. */ | |
464 | @@ -69,7 +63,8 @@ gelf_update_dyn (data, ndx, src) | |
465 | } | |
466 | ||
467 | /* Check whether we have to resize the data buffer. */ | |
468 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size)) | |
469 | + if (INVALID_NDX (ndx, Elf32_Dyn) | |
470 | + || unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size)) | |
471 | { | |
472 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
473 | goto out; | |
474 | @@ -83,7 +78,8 @@ gelf_update_dyn (data, ndx, src) | |
475 | else | |
476 | { | |
477 | /* Check whether we have to resize the data buffer. */ | |
478 | - if (unlikely ((ndx + 1) * sizeof (Elf64_Dyn) > data_scn->d.d_size)) | |
479 | + if (INVALID_NDX (ndx, Elf64_Dyn) | |
480 | + || unlikely ((ndx + 1) * sizeof (Elf64_Dyn) > data_scn->d.d_size)) | |
481 | { | |
482 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
483 | goto out; | |
484 | --- elfutils-0.108/libelf/elf_begin.c.jj 2005-05-09 06:33:49.000000000 +0200 | |
485 | +++ elfutils-0.108/libelf/elf_begin.c 2005-05-14 00:29:34.000000000 +0200 | |
486 | @@ -220,7 +220,7 @@ file_read_elf (int fildes, void *map_add | |
487 | ||
488 | /* Determine the number of sections. */ | |
489 | scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize); | |
490 | - if (scncnt == (size_t) -1l) | |
491 | + if (scncnt == (size_t) -1l || scncnt > SIZE_MAX / sizeof (Elf_Scn)) | |
492 | /* Could not determine the number of sections. */ | |
493 | return NULL; | |
494 | ||
495 | --- elfutils-0.108/libelf/gelf_getversym.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
496 | +++ elfutils-0.108/libelf/gelf_getversym.c 2005-05-14 01:31:25.000000000 +0200 | |
497 | @@ -1,5 +1,5 @@ | |
498 | /* Get symbol version information at the given index. | |
499 | - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. | |
500 | + Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc. | |
501 | Written by Ulrich Drepper <drepper@redhat.com>, 1999. | |
502 | ||
503 | This program is free software; you can redistribute it and/or modify | |
504 | @@ -59,7 +59,8 @@ gelf_getversym (data, ndx, dst) | |
505 | ||
506 | /* The data is already in the correct form. Just make sure the | |
507 | index is OK. */ | |
508 | - if (unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size)) | |
509 | + if (INVALID_NDX (ndx, GElf_Versym) | |
510 | + || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size)) | |
511 | { | |
512 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
513 | result = NULL; | |
514 | --- elfutils-0.108/libelf/elf32_newphdr.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
515 | +++ elfutils-0.108/libelf/elf32_newphdr.c 2005-05-14 01:17:53.000000000 +0200 | |
516 | @@ -1,5 +1,5 @@ | |
517 | /* Create new ELF program header table. | |
518 | - Copyright (C) 1999, 2000, 2002 Red Hat, Inc. | |
519 | + Copyright (C) 1999, 2000, 2002, 2005 Red Hat, Inc. | |
520 | Written by Ulrich Drepper <drepper@redhat.com>, 1998. | |
521 | ||
522 | This program is free software; you can redistribute it and/or modify | |
523 | @@ -91,6 +91,12 @@ elfw2(LIBELFBITS,newphdr) (elf, count) | |
524 | else if (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum != count | |
525 | || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL) | |
526 | { | |
527 | + if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr)))) | |
528 | + { | |
529 | + result = NULL; | |
530 | + goto out; | |
531 | + } | |
532 | + | |
533 | /* Allocate a new program header with the appropriate number of | |
534 | elements. */ | |
535 | result = (ElfW2(LIBELFBITS,Phdr) *) | |
536 | --- elfutils-0.108/libelf/gelf_getdyn.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
537 | +++ elfutils-0.108/libelf/gelf_getdyn.c 2005-05-14 01:31:25.000000000 +0200 | |
538 | @@ -1,5 +1,5 @@ | |
539 | /* Get information from dynamic table at the given index. | |
540 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
541 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
542 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
543 | ||
544 | This program is free software; you can redistribute it and/or modify | |
545 | @@ -60,7 +60,8 @@ gelf_getdyn (data, ndx, dst) | |
546 | table entries has to be adopted. The user better has provided | |
547 | a buffer where we can store the information. While copying the | |
548 | data we are converting the format. */ | |
549 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size)) | |
550 | + if (INVALID_NDX (ndx, Elf32_Dyn) | |
551 | + || unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size)) | |
552 | { | |
553 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
554 | goto out; | |
555 | @@ -81,7 +82,8 @@ gelf_getdyn (data, ndx, dst) | |
556 | ||
557 | /* The data is already in the correct form. Just make sure the | |
558 | index is OK. */ | |
559 | - if (unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size)) | |
560 | + if (INVALID_NDX (ndx, GElf_Dyn) | |
561 | + || unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size)) | |
562 | { | |
563 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
564 | goto out; | |
565 | --- elfutils-0.108/libelf/elf_getarsym.c.jj 2005-02-06 10:14:52.000000000 +0100 | |
566 | +++ elfutils-0.108/libelf/elf_getarsym.c 2005-05-14 01:37:47.000000000 +0200 | |
567 | @@ -144,6 +144,9 @@ elf_getarsym (elf, ptr) | |
568 | size_t index_size = atol (tmpbuf); | |
569 | ||
570 | if (SARMAG + sizeof (struct ar_hdr) + index_size > elf->maximum_size | |
571 | +#if SIZE_MAX <= 4294967295U | |
572 | + || n >= SIZE_MAX / sizeof (Elf_Arsym) | |
573 | +#endif | |
574 | || n * sizeof (uint32_t) > index_size) | |
575 | { | |
576 | /* This index table cannot be right since it does not fit into | |
577 | --- elfutils-0.108/libelf/libelfP.h.jj 2005-03-30 03:42:32.000000000 +0200 | |
578 | +++ elfutils-0.108/libelf/libelfP.h 2005-05-14 01:28:47.000000000 +0200 | |
579 | @@ -531,4 +531,13 @@ extern uint32_t __libelf_crc32 (uint32_t | |
580 | } while (0) | |
581 | #endif | |
582 | ||
583 | +/* Convenience macro. Assumes int NDX and TYPE with size at least | |
584 | + 2 bytes. */ | |
585 | +#if SIZE_MAX > 4294967295U | |
586 | +# define INVALID_NDX(ndx, type) unlikely (ndx < 0) | |
587 | +#else | |
588 | +# define INVALID_NDX(ndx, type) \ | |
589 | + unlikely ((unsigned int) (ndx) >= SIZE_MAX / sizeof (type)) | |
590 | +#endif | |
591 | + | |
592 | #endif /* libelfP.h */ | |
593 | --- elfutils-0.108/libelf/gelf_getlib.c.jj 2004-01-23 19:22:56.000000000 +0100 | |
594 | +++ elfutils-0.108/libelf/gelf_getlib.c 2005-05-14 01:31:25.000000000 +0200 | |
595 | @@ -1,5 +1,5 @@ | |
596 | /* Get library from table at the given index. | |
597 | - Copyright (C) 2004 Red Hat, Inc. | |
598 | + Copyright (C) 2004, 2005 Red Hat, Inc. | |
599 | Written by Ulrich Drepper <drepper@redhat.com>, 2004. | |
600 | ||
601 | This program is free software; you can redistribute it and/or modify | |
602 | @@ -53,7 +53,8 @@ gelf_getlib (data, ndx, dst) | |
603 | /* The data is already in the correct form. Just make sure the | |
604 | index is OK. */ | |
605 | GElf_Lib *result = NULL; | |
606 | - if (unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size)) | |
607 | + if (INVALID_NDX (ndx, GElf_Lib) | |
608 | + || unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size)) | |
609 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
610 | else | |
611 | { | |
612 | --- elfutils-0.108/libelf/gelf_update_symshndx.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
613 | +++ elfutils-0.108/libelf/gelf_update_symshndx.c 2005-05-14 01:31:25.000000000 +0200 | |
614 | @@ -1,6 +1,6 @@ | |
615 | /* Update symbol information and section index in symbol table at the | |
616 | given index. | |
617 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
618 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
619 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
620 | ||
621 | This program is free software; you can redistribute it and/or modify | |
622 | @@ -44,12 +44,6 @@ gelf_update_symshndx (symdata, shndxdata | |
623 | if (symdata == NULL) | |
624 | return 0; | |
625 | ||
626 | - if (unlikely (ndx < 0)) | |
627 | - { | |
628 | - __libelf_seterrno (ELF_E_INVALID_INDEX); | |
629 | - return 0; | |
630 | - } | |
631 | - | |
632 | if (unlikely (symdata_scn->d.d_type != ELF_T_SYM)) | |
633 | { | |
634 | /* The type of the data better should match. */ | |
635 | @@ -95,7 +89,8 @@ gelf_update_symshndx (symdata, shndxdata | |
636 | } | |
637 | ||
638 | /* Check whether we have to resize the data buffer. */ | |
639 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size)) | |
640 | + if (INVALID_NDX (ndx, Elf32_Sym) | |
641 | + || unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size)) | |
642 | { | |
643 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
644 | goto out; | |
645 | @@ -118,7 +113,8 @@ gelf_update_symshndx (symdata, shndxdata | |
646 | else | |
647 | { | |
648 | /* Check whether we have to resize the data buffer. */ | |
649 | - if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size)) | |
650 | + if (INVALID_NDX (ndx, Elf64_Sym) | |
651 | + || unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size)) | |
652 | { | |
653 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
654 | goto out; | |
655 | --- elfutils-0.108/libelf/elf32_getshdr.c.jj 2005-02-06 10:14:52.000000000 +0100 | |
656 | +++ elfutils-0.108/libelf/elf32_getshdr.c 2005-05-14 00:32:57.000000000 +0200 | |
657 | @@ -66,7 +66,8 @@ elfw2(LIBELFBITS,getshdr) (scn) | |
658 | goto out; | |
659 | ||
660 | size_t shnum; | |
661 | - if (INTUSE (elf_getshnum) (elf, &shnum) != 0) | |
662 | + if (INTUSE (elf_getshnum) (elf, &shnum) != 0 | |
663 | + || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr))) | |
664 | goto out; | |
665 | size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr)); | |
666 | ||
667 | --- elfutils-0.108/libelf/gelf_update_rela.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
668 | +++ elfutils-0.108/libelf/gelf_update_rela.c 2005-05-14 01:31:25.000000000 +0200 | |
669 | @@ -1,5 +1,5 @@ | |
670 | /* Update RELA relocation information at given index. | |
671 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
672 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
673 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
674 | ||
675 | This program is free software; you can redistribute it and/or modify | |
676 | @@ -35,12 +35,6 @@ gelf_update_rela (Elf_Data *dst, int ndx | |
677 | if (dst == NULL) | |
678 | return 0; | |
679 | ||
680 | - if (unlikely (ndx < 0)) | |
681 | - { | |
682 | - __libelf_seterrno (ELF_E_INVALID_INDEX); | |
683 | - return 0; | |
684 | - } | |
685 | - | |
686 | if (unlikely (data_scn->d.d_type != ELF_T_RELA)) | |
687 | { | |
688 | /* The type of the data better should match. */ | |
689 | @@ -68,7 +62,8 @@ gelf_update_rela (Elf_Data *dst, int ndx | |
690 | } | |
691 | ||
692 | /* Check whether we have to resize the data buffer. */ | |
693 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size)) | |
694 | + if (INVALID_NDX (ndx, Elf32_Rela) | |
695 | + || unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size)) | |
696 | { | |
697 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
698 | goto out; | |
699 | @@ -84,7 +79,8 @@ gelf_update_rela (Elf_Data *dst, int ndx | |
700 | else | |
701 | { | |
702 | /* Check whether we have to resize the data buffer. */ | |
703 | - if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size)) | |
704 | + if (INVALID_NDX (ndx, Elf64_Rela) | |
705 | + || unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size)) | |
706 | { | |
707 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
708 | goto out; | |
709 | --- elfutils-0.108/libelf/gelf_update_versym.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
710 | +++ elfutils-0.108/libelf/gelf_update_versym.c 2005-05-14 01:31:25.000000000 +0200 | |
711 | @@ -1,5 +1,5 @@ | |
712 | /* Update symbol version information. | |
713 | - Copyright (C) 2001, 2002 Red Hat, Inc. | |
714 | + Copyright (C) 2001, 2002, 2005 Red Hat, Inc. | |
715 | Written by Ulrich Drepper <drepper@redhat.com>, 2001. | |
716 | ||
717 | This program is free software; you can redistribute it and/or modify | |
718 | @@ -42,7 +42,7 @@ gelf_update_versym (data, ndx, src) | |
719 | assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym)); | |
720 | ||
721 | /* Check whether we have to resize the data buffer. */ | |
722 | - if (unlikely (ndx < 0) | |
723 | + if (INVALID_NDX (ndx, GElf_Versym) | |
724 | || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data_scn->d.d_size)) | |
725 | { | |
726 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
727 | --- elfutils-0.108/libelf/gelf_update_rel.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
728 | +++ elfutils-0.108/libelf/gelf_update_rel.c 2005-05-14 01:31:25.000000000 +0200 | |
729 | @@ -1,5 +1,5 @@ | |
730 | /* Update REL relocation information at given index. | |
731 | - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. | |
732 | + Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. | |
733 | Written by Ulrich Drepper <drepper@redhat.com>, 2000. | |
734 | ||
735 | This program is free software; you can redistribute it and/or modify | |
736 | @@ -35,12 +35,6 @@ gelf_update_rel (Elf_Data *dst, int ndx, | |
737 | if (dst == NULL) | |
738 | return 0; | |
739 | ||
740 | - if (unlikely (ndx < 0)) | |
741 | - { | |
742 | - __libelf_seterrno (ELF_E_INVALID_INDEX); | |
743 | - return 0; | |
744 | - } | |
745 | - | |
746 | if (unlikely (data_scn->d.d_type != ELF_T_REL)) | |
747 | { | |
748 | /* The type of the data better should match. */ | |
749 | @@ -66,7 +60,8 @@ gelf_update_rel (Elf_Data *dst, int ndx, | |
750 | } | |
751 | ||
752 | /* Check whether we have to resize the data buffer. */ | |
753 | - if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size)) | |
754 | + if (INVALID_NDX (ndx, Elf32_Rel) | |
755 | + || unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size)) | |
756 | { | |
757 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
758 | goto out; | |
759 | @@ -81,7 +76,8 @@ gelf_update_rel (Elf_Data *dst, int ndx, | |
760 | else | |
761 | { | |
762 | /* Check whether we have to resize the data buffer. */ | |
763 | - if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size)) | |
764 | + if (INVALID_NDX (ndx, Elf64_Rel) | |
765 | + || unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size)) | |
766 | { | |
767 | __libelf_seterrno (ELF_E_INVALID_INDEX); | |
768 | goto out; | |
769 | --- elfutils-0.108/src/elflint.c.jj 2005-05-07 01:46:26.000000000 +0200 | |
770 | +++ elfutils-0.108/src/elflint.c 2005-05-14 02:22:24.000000000 +0200 | |
771 | @@ -111,6 +111,9 @@ static uint32_t shstrndx; | |
772 | /* Array to count references in section groups. */ | |
773 | static int *scnref; | |
774 | ||
775 | +/* Number of sections. */ | |
776 | +static unsigned int shnum; | |
777 | + | |
778 | ||
779 | int | |
780 | main (int argc, char *argv[]) | |
781 | @@ -300,10 +303,17 @@ section_name (Ebl *ebl, int idx) | |
782 | { | |
783 | GElf_Shdr shdr_mem; | |
784 | GElf_Shdr *shdr; | |
785 | + const char *ret; | |
786 | + | |
787 | + if ((unsigned int) idx > shnum) | |
788 | + return "<invalid>"; | |
789 | ||
790 | shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem); | |
791 | ||
792 | - return elf_strptr (ebl->elf, shstrndx, shdr->sh_name); | |
793 | + ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); | |
794 | + if (ret == NULL) | |
795 | + return "<invalid>"; | |
796 | + return ret; | |
797 | } | |
798 | ||
799 | ||
800 | @@ -325,10 +335,6 @@ static const int valid_e_machine[] = | |
801 | (sizeof (valid_e_machine) / sizeof (valid_e_machine[0])) | |
802 | ||
803 | ||
804 | -/* Number of sections. */ | |
805 | -static unsigned int shnum; | |
806 | - | |
807 | - | |
808 | static void | |
809 | check_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size) | |
810 | { | |
811 | @@ -608,7 +614,8 @@ check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, | |
812 | xndxdata = NULL; | |
813 | } | |
814 | ||
815 | - if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)) | |
816 | + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT); | |
817 | + if (shdr->sh_entsize != sh_entsize) | |
818 | ERROR (gettext ("\ | |
819 | section [%2zu] '%s': entry size is does not match ElfXX_Sym\n"), | |
820 | cnt, section_name (ebl, cnt)); | |
821 | @@ -646,7 +653,7 @@ section [%2d] '%s': XINDEX for zeroth en | |
822 | xndxscnidx, section_name (ebl, xndxscnidx)); | |
823 | } | |
824 | ||
825 | - for (cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) | |
826 | + for (cnt = 1; cnt < shdr->sh_size / sh_entsize; ++cnt) | |
827 | { | |
828 | sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx); | |
829 | if (sym == NULL) | |
830 | @@ -664,7 +671,8 @@ section [%2d] '%s': symbol %zu: invalid | |
831 | else | |
832 | { | |
833 | name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name); | |
834 | - assert (name != NULL); | |
835 | + assert (name != NULL | |
836 | + || strshdr->sh_type != SHT_STRTAB); | |
837 | } | |
838 | ||
839 | if (sym->st_shndx == SHN_XINDEX) | |
840 | @@ -954,7 +962,7 @@ is_rel_dyn (Ebl *ebl, GElf_Ehdr *ehdr, i | |
841 | const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem); | |
842 | assert (rcshdr != NULL); | |
843 | ||
844 | - if (rcshdr->sh_type == SHT_DYNAMIC) | |
845 | + if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize) | |
846 | { | |
847 | /* Found the dynamic section. Look through it. */ | |
848 | Elf_Data *d = elf_getdata (scn, NULL); | |
849 | @@ -964,14 +972,17 @@ is_rel_dyn (Ebl *ebl, GElf_Ehdr *ehdr, i | |
850 | { | |
851 | GElf_Dyn dyn_mem; | |
852 | GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem); | |
853 | - assert (dyn != NULL); | |
854 | + | |
855 | + if (dyn == NULL) | |
856 | + break; | |
857 | ||
858 | if (dyn->d_tag == DT_RELCOUNT) | |
859 | { | |
860 | /* Found it. One last check: does the number | |
861 | specified number of relative relocations exceed | |
862 | the total number of relocations? */ | |
863 | - if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) | |
864 | + if (shdr->sh_entsize | |
865 | + && dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize) | |
866 | ERROR (gettext ("\ | |
867 | section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"), | |
868 | idx, section_name (ebl, idx), | |
869 | @@ -1048,7 +1059,8 @@ section [%2d] '%s': no relocations for m | |
870 | } | |
871 | } | |
872 | ||
873 | - if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT)) | |
874 | + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT); | |
875 | + if (shdr->sh_entsize != sh_entsize) | |
876 | ERROR (gettext ("\ | |
877 | section [%2d] '%s': section entry size does not match ElfXX_Rela\n"), | |
878 | idx, section_name (ebl, idx)); | |
879 | @@ -1058,7 +1070,7 @@ section [%2d] '%s': section entry size d | |
880 | GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); | |
881 | Elf_Data *symdata = elf_getdata (symscn, NULL); | |
882 | ||
883 | - for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) | |
884 | + for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) | |
885 | { | |
886 | GElf_Rela rela_mem; | |
887 | GElf_Rela *rela; | |
888 | @@ -1183,7 +1195,8 @@ section [%2d] '%s': no relocations for m | |
889 | } | |
890 | } | |
891 | ||
892 | - if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT)) | |
893 | + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT); | |
894 | + if (shdr->sh_entsize != sh_entsize) | |
895 | ERROR (gettext ("\ | |
896 | section [%2d] '%s': section entry size does not match ElfXX_Rel\n"), | |
897 | idx, section_name (ebl, idx)); | |
898 | @@ -1193,7 +1206,7 @@ section [%2d] '%s': section entry size d | |
899 | GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); | |
900 | Elf_Data *symdata = elf_getdata (symscn, NULL); | |
901 | ||
902 | - for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) | |
903 | + for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) | |
904 | { | |
905 | GElf_Rel rel_mem; | |
906 | GElf_Rel *rel; | |
907 | @@ -1341,7 +1354,8 @@ section [%2d] '%s': referenced as string | |
908 | shdr->sh_link, section_name (ebl, shdr->sh_link), | |
909 | idx, section_name (ebl, idx)); | |
910 | ||
911 | - if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT)) | |
912 | + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT); | |
913 | + if (shdr->sh_entsize != sh_entsize) | |
914 | ERROR (gettext ("\ | |
915 | section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"), | |
916 | idx, section_name (ebl, idx)); | |
917 | @@ -1351,7 +1365,7 @@ section [%2d] '%s': section entry size d | |
918 | idx, section_name (ebl, idx)); | |
919 | ||
920 | bool non_null_warned = false; | |
921 | - for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) | |
922 | + for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) | |
923 | { | |
924 | GElf_Dyn dyn_mem; | |
925 | GElf_Dyn *dyn; | |
926 | @@ -1502,6 +1516,8 @@ section [%2d] '%s': entry size does not | |
927 | idx, section_name (ebl, idx)); | |
928 | ||
929 | if (symshdr != NULL | |
930 | + && shdr->sh_entsize | |
931 | + && symshdr->sh_entsize | |
932 | && (shdr->sh_size / shdr->sh_entsize | |
933 | < symshdr->sh_size / symshdr->sh_entsize)) | |
934 | ERROR (gettext ("\ | |
935 | @@ -1530,6 +1546,12 @@ section [%2d] '%s': extended section ind | |
936 | } | |
937 | ||
938 | data = elf_getdata (scn, NULL); | |
939 | + if (data == NULL) | |
940 | + { | |
941 | + ERROR (gettext ("section [%2d] '%s': cannot get section data\n"), | |
942 | + idx, section_name (ebl, idx)); | |
943 | + return; | |
944 | + } | |
945 | ||
946 | if (*((Elf32_Word *) data->d_buf) != 0) | |
947 | ERROR (gettext ("symbol 0 should have zero extended section index\n")); | |
948 | @@ -1613,7 +1635,7 @@ section [%2d] '%s': hash table section i | |
949 | idx, section_name (ebl, idx), (long int) shdr->sh_size, | |
950 | (long int) ((2 + nbucket + nchain) * shdr->sh_entsize)); | |
951 | ||
952 | - if (symshdr != NULL) | |
953 | + if (symshdr != NULL && symshdr->sh_entsize) | |
954 | { | |
955 | size_t symsize = symshdr->sh_size / symshdr->sh_entsize; | |
956 | size_t cnt; | |
957 | @@ -1910,8 +1932,10 @@ section [%2d] '%s' refers in sh_link to | |
958 | return; | |
959 | } | |
960 | ||
961 | - if (shdr->sh_size / shdr->sh_entsize | |
962 | - != symshdr->sh_size / symshdr->sh_entsize) | |
963 | + if (shdr->sh_entsize | |
964 | + && symshdr->sh_entsize | |
965 | + && shdr->sh_size / shdr->sh_entsize | |
966 | + != symshdr->sh_size / symshdr->sh_entsize) | |
967 | ERROR (gettext ("\ | |
968 | section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"), | |
969 | idx, section_name (ebl, idx), | |
970 | ||
971 | --- elfutils-0.108/libelf/elf32_getphdr.c.jj 2005-02-06 10:14:52.000000000 +0100 | |
972 | +++ elfutils-0.108/libelf/elf32_getphdr.c 2005-05-17 16:53:41.000000000 +0200 | |
973 | @@ -80,6 +80,16 @@ elfw2(LIBELFBITS,getphdr) (elf) | |
974 | ||
975 | if (elf->map_address != NULL) | |
976 | { | |
977 | + /* First see whether the information in the ELF header is | |
978 | + valid and it does not ask for too much. */ | |
979 | + if (unlikely (ehdr->e_phoff >= elf->maximum_size) | |
980 | + || unlikely (ehdr->e_phoff + size > elf->maximum_size)) | |
981 | + { | |
982 | + /* Something is wrong. */ | |
983 | + __libelf_seterrno (ELF_E_INVALID_PHDR); | |
984 | + goto out; | |
985 | + } | |
986 | + | |
987 | /* All the data is already mapped. Use it. */ | |
988 | if (ehdr->e_ident[EI_DATA] == MY_ELFDATA | |
989 | && (ALLOW_UNALIGNED | |
990 | --- elfutils-0.108/libelf/elf_getshstrndx.c.jj 2004-01-05 21:45:05.000000000 +0100 | |
991 | +++ elfutils-0.108/libelf/elf_getshstrndx.c 2005-05-17 15:42:32.000000000 +0200 | |
992 | @@ -1,5 +1,5 @@ | |
993 | /* Return section index of section header string table. | |
994 | - Copyright (C) 2002 Red Hat, Inc. | |
995 | + Copyright (C) 2002, 2005 Red Hat, Inc. | |
996 | Written by Ulrich Drepper <drepper@redhat.com>, 2002. | |
997 | ||
998 | This program is free software; you can redistribute it and/or modify | |
999 | @@ -90,10 +90,25 @@ elf_getshstrndx (elf, dst) | |
1000 | if (elf->map_address != NULL | |
1001 | && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA | |
1002 | && (ALLOW_UNALIGNED | |
1003 | - || (((size_t) ((char *) elf->map_address + offset)) | |
1004 | + || (((size_t) ((char *) elf->map_address | |
1005 | + + elf->start_offset + offset)) | |
1006 | & (__alignof__ (Elf32_Shdr) - 1)) == 0)) | |
1007 | - /* We can directly access the memory. */ | |
1008 | - num = ((Elf32_Shdr *) (elf->map_address + offset))->sh_link; | |
1009 | + { | |
1010 | + /* First see whether the information in the ELF header is | |
1011 | + valid and it does not ask for too much. */ | |
1012 | + if (unlikely (offset + sizeof (Elf32_Shdr) | |
1013 | + > elf->maximum_size)) | |
1014 | + { | |
1015 | + /* Something is wrong. */ | |
1016 | + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); | |
1017 | + result = -1; | |
1018 | + goto out; | |
1019 | + } | |
1020 | + | |
1021 | + /* We can directly access the memory. */ | |
1022 | + num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset | |
1023 | + + offset))->sh_link; | |
1024 | + } | |
1025 | else | |
1026 | { | |
1027 | /* We avoid reading in all the section headers. Just read | |
1028 | @@ -129,10 +144,25 @@ elf_getshstrndx (elf, dst) | |
1029 | if (elf->map_address != NULL | |
1030 | && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA | |
1031 | && (ALLOW_UNALIGNED | |
1032 | - || (((size_t) ((char *) elf->map_address + offset)) | |
1033 | + || (((size_t) ((char *) elf->map_address | |
1034 | + + elf->start_offset + offset)) | |
1035 | & (__alignof__ (Elf64_Shdr) - 1)) == 0)) | |
1036 | - /* We can directly access the memory. */ | |
1037 | - num = ((Elf64_Shdr *) (elf->map_address + offset))->sh_link; | |
1038 | + { | |
1039 | + /* First see whether the information in the ELF header is | |
1040 | + valid and it does not ask for too much. */ | |
1041 | + if (unlikely (offset + sizeof (Elf64_Shdr) | |
1042 | + > elf->maximum_size)) | |
1043 | + { | |
1044 | + /* Something is wrong. */ | |
1045 | + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); | |
1046 | + result = -1; | |
1047 | + goto out; | |
1048 | + } | |
1049 | + | |
1050 | + /* We can directly access the memory. */ | |
1051 | + num = ((Elf64_Shdr *) (elf->map_address | |
1052 | + + elf->start_offset + offset))->sh_link; | |
1053 | + } | |
1054 | else | |
1055 | { | |
1056 | /* We avoid reading in all the section headers. Just read | |
1057 | --- elfutils-0.108/libelf/elf32_getshdr.c.jj 2005-05-14 00:32:57.000000000 +0200 | |
1058 | +++ elfutils-0.108/libelf/elf32_getshdr.c 2005-05-17 15:27:52.000000000 +0200 | |
1059 | @@ -71,7 +71,7 @@ elfw2(LIBELFBITS,getshdr) (scn) | |
1060 | goto out; | |
1061 | size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr)); | |
1062 | ||
1063 | - /* Allocate memory for the program headers. We know the number | |
1064 | + /* Allocate memory for the section headers. We know the number | |
1065 | of entries from the ELF header. */ | |
1066 | ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr = | |
1067 | (ElfW2(LIBELFBITS,Shdr) *) malloc (size); | |
1068 | @@ -93,6 +93,16 @@ elfw2(LIBELFBITS,getshdr) (scn) | |
1069 | && (ehdr->e_shoff | |
1070 | & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0)); | |
1071 | ||
1072 | + /* First see whether the information in the ELF header is | |
1073 | + valid and it does not ask for too much. */ | |
1074 | + if (unlikely (ehdr->e_shoff >= elf->maximum_size) | |
1075 | + || unlikely (ehdr->e_shoff + size > elf->maximum_size)) | |
1076 | + { | |
1077 | + /* Something is wrong. */ | |
1078 | + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); | |
1079 | + goto free_and_out; | |
1080 | + } | |
1081 | + | |
1082 | /* Now copy the data and at the same time convert the byte | |
1083 | order. */ | |
1084 | if (ALLOW_UNALIGNED | |
1085 | --- elfutils-0.108/libelf/elf_begin.c.jj 2005-05-17 16:18:51.000000000 +0200 | |
1086 | +++ elfutils-0.108/libelf/elf_begin.c 2005-05-17 17:31:37.000000000 +0200 | |
1087 | @@ -77,7 +77,11 @@ get_shnum (void *map_address, unsigned c | |
1088 | || (((size_t) ((char *) map_address + offset)) | |
1089 | & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr)) | |
1090 | - 1)) == 0)) | |
1091 | - ehdr.p = (char *) map_address + offset; | |
1092 | + { | |
1093 | + ehdr.p = (char *) map_address + offset; | |
1094 | + if (maxsize < (is32 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr))) | |
1095 | + return (size_t) -1l; | |
1096 | + } | |
1097 | else | |
1098 | { | |
1099 | /* We have to read the data from the file. */ | |
1100 | @@ -111,7 +115,8 @@ get_shnum (void *map_address, unsigned c | |
1101 | ||
1102 | if (unlikely (result == 0) && ehdr.e32->e_shoff != 0) | |
1103 | { | |
1104 | - if (offset + ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize) | |
1105 | + if (unlikely (ehdr.e32->e_shoff >= maxsize) | |
1106 | + || unlikely (ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize)) | |
1107 | /* Cannot read the first section header. */ | |
1108 | return (size_t) -1l; | |
1109 | ||
1110 | @@ -147,7 +152,8 @@ get_shnum (void *map_address, unsigned c | |
1111 | ||
1112 | if (unlikely (result == 0) && ehdr.e64->e_shoff != 0) | |
1113 | { | |
1114 | - if (offset + ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize) | |
1115 | + if (unlikely (ehdr.e64->e_shoff >= maxsize) | |
1116 | + || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)) | |
1117 | /* Cannot read the first section header. */ | |
1118 | return (size_t) -1l; | |
1119 | ||
1120 | @@ -220,10 +226,19 @@ file_read_elf (int fildes, void *map_add | |
1121 | ||
1122 | /* Determine the number of sections. */ | |
1123 | scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize); | |
1124 | - if (scncnt == (size_t) -1l || scncnt > SIZE_MAX / sizeof (Elf_Scn)) | |
1125 | + if (scncnt == (size_t) -1l) | |
1126 | /* Could not determine the number of sections. */ | |
1127 | return NULL; | |
1128 | ||
1129 | + /* Check for too many sections. */ | |
1130 | + if (e_ident[EI_CLASS] == ELFCLASS32) | |
1131 | + { | |
1132 | + if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr))) | |
1133 | + return NULL; | |
1134 | + } | |
1135 | + else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr))) | |
1136 | + return NULL; | |
1137 | + | |
1138 | /* We can now allocate the memory. */ | |
1139 | elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, | |
1140 | ELF_K_ELF, scncnt * sizeof (Elf_Scn)); | |
1141 | @@ -255,15 +270,31 @@ file_read_elf (int fildes, void *map_add | |
1142 | /* We can use the mmapped memory. */ | |
1143 | elf->state.elf32.ehdr = | |
1144 | (Elf32_Ehdr *) ((char *) map_address + offset); | |
1145 | + if (unlikely (elf->state.elf32.ehdr->e_shoff >= maxsize) | |
1146 | + || unlikely (elf->state.elf32.ehdr->e_shoff | |
1147 | + + scncnt * sizeof (Elf32_Shdr) > maxsize)) | |
1148 | + { | |
1149 | + free_and_out: | |
1150 | + __libelf_seterrno (ELF_E_INVALID_FILE); | |
1151 | + free (elf); | |
1152 | + return NULL; | |
1153 | + } | |
1154 | elf->state.elf32.shdr = | |
1155 | (Elf32_Shdr *) ((char *) map_address + offset | |
1156 | + elf->state.elf32.ehdr->e_shoff); | |
1157 | if (elf->state.elf32.ehdr->e_phnum) | |
1158 | - /* Assign a value only if there really is a program | |
1159 | - header. Otherwise the value remains NULL. */ | |
1160 | - elf->state.elf32.phdr | |
1161 | - = (Elf32_Phdr *) ((char *) map_address + offset | |
1162 | - + elf->state.elf32.ehdr->e_phoff); | |
1163 | + { | |
1164 | + /* Assign a value only if there really is a program | |
1165 | + header. Otherwise the value remains NULL. */ | |
1166 | + if (unlikely (elf->state.elf32.ehdr->e_phoff >= maxsize) | |
1167 | + || unlikely (elf->state.elf32.ehdr->e_phoff | |
1168 | + + elf->state.elf32.ehdr->e_phnum | |
1169 | + * sizeof (Elf32_Phdr) > maxsize)) | |
1170 | + goto free_and_out; | |
1171 | + elf->state.elf32.phdr | |
1172 | + = (Elf32_Phdr *) ((char *) map_address + offset | |
1173 | + + elf->state.elf32.ehdr->e_phoff); | |
1174 | + } | |
1175 | ||
1176 | for (size_t cnt = 0; cnt < scncnt; ++cnt) | |
1177 | { | |
1178 | @@ -285,8 +316,7 @@ file_read_elf (int fildes, void *map_add | |
1179 | sizeof (Elf32_Ehdr), offset) != sizeof (Elf32_Ehdr)) | |
1180 | { | |
1181 | /* We must be able to read the ELF header. */ | |
1182 | - __libelf_seterrno (ELF_E_INVALID_FILE); | |
1183 | - return NULL; | |
1184 | + goto free_and_out; | |
1185 | } | |
1186 | ||
1187 | if (e_ident[EI_DATA] != MY_ELFDATA) | |
1188 | @@ -340,15 +370,26 @@ file_read_elf (int fildes, void *map_add | |
1189 | /* We can use the mmapped memory. */ | |
1190 | elf->state.elf64.ehdr = | |
1191 | (Elf64_Ehdr *) ((char *) map_address + offset); | |
1192 | + if (unlikely (elf->state.elf64.ehdr->e_shoff >= maxsize) | |
1193 | + || unlikely (elf->state.elf64.ehdr->e_shoff | |
1194 | + + scncnt * sizeof (Elf64_Shdr) > maxsize)) | |
1195 | + goto free_and_out; | |
1196 | elf->state.elf64.shdr = | |
1197 | (Elf64_Shdr *) ((char *) map_address + offset | |
1198 | + elf->state.elf64.ehdr->e_shoff); | |
1199 | if (elf->state.elf64.ehdr->e_phnum) | |
1200 | - /* Assign a value only if there really is a program | |
1201 | - header. Otherwise the value remains NULL. */ | |
1202 | - elf->state.elf64.phdr | |
1203 | - = (Elf64_Phdr *) ((char *) map_address + offset | |
1204 | - + elf->state.elf64.ehdr->e_phoff); | |
1205 | + { | |
1206 | + /* Assign a value only if there really is a program | |
1207 | + header. Otherwise the value remains NULL. */ | |
1208 | + if (unlikely (elf->state.elf64.ehdr->e_phoff >= maxsize) | |
1209 | + || unlikely (elf->state.elf64.ehdr->e_phoff | |
1210 | + + elf->state.elf64.ehdr->e_phnum | |
1211 | + * sizeof (Elf64_Phdr) > maxsize)) | |
1212 | + goto free_and_out; | |
1213 | + elf->state.elf64.phdr | |
1214 | + = (Elf64_Phdr *) ((char *) map_address + offset | |
1215 | + + elf->state.elf64.ehdr->e_phoff); | |
1216 | + } | |
1217 | ||
1218 | for (size_t cnt = 0; cnt < scncnt; ++cnt) | |
1219 | { | |
1220 | @@ -370,8 +411,7 @@ file_read_elf (int fildes, void *map_add | |
1221 | sizeof (Elf64_Ehdr), offset) != sizeof (Elf64_Ehdr)) | |
1222 | { | |
1223 | /* We must be able to read the ELF header. */ | |
1224 | - __libelf_seterrno (ELF_E_INVALID_FILE); | |
1225 | - return NULL; | |
1226 | + goto free_and_out; | |
1227 | } | |
1228 | ||
1229 | if (e_ident[EI_DATA] != MY_ELFDATA) | |
1230 | --- elfutils-0.108/src/elflint.c.jj 2005-05-14 02:22:24.000000000 +0200 | |
1231 | +++ elfutils-0.108/src/elflint.c 2005-05-17 18:02:00.000000000 +0200 | |
1232 | @@ -309,6 +309,8 @@ section_name (Ebl *ebl, int idx) | |
1233 | return "<invalid>"; | |
1234 | ||
1235 | shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem); | |
1236 | + if (shdr == NULL) | |
1237 | + return "<invalid>"; | |
1238 | ||
1239 | ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); | |
1240 | if (ret == NULL) | |
1241 | @@ -1639,19 +1641,26 @@ section [%2d] '%s': hash table section i | |
1242 | { | |
1243 | size_t symsize = symshdr->sh_size / symshdr->sh_entsize; | |
1244 | size_t cnt; | |
1245 | + Elf32_Word *buf, *end; | |
1246 | ||
1247 | if (nchain < symshdr->sh_size / symshdr->sh_entsize) | |
1248 | ERROR (gettext ("section [%2d] '%s': chain array not large enough\n"), | |
1249 | idx, section_name (ebl, idx)); | |
1250 | ||
1251 | + buf = ((Elf32_Word *) data->d_buf) + 2; | |
1252 | + end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size); | |
1253 | for (cnt = 2; cnt < 2 + nbucket; ++cnt) | |
1254 | - if (((Elf32_Word *) data->d_buf)[cnt] >= symsize) | |
1255 | + if (buf >= end) | |
1256 | + return; | |
1257 | + else if (*buf++ >= symsize) | |
1258 | ERROR (gettext ("\ | |
1259 | section [%2d] '%s': hash bucket reference %zu out of bounds\n"), | |
1260 | idx, section_name (ebl, idx), cnt - 2); | |
1261 | ||
1262 | for (; cnt < 2 + nbucket + nchain; ++cnt) | |
1263 | - if (((Elf32_Word *) data->d_buf)[cnt] >= symsize) | |
1264 | + if (buf >= end) | |
1265 | + return; | |
1266 | + else if (*buf++ >= symsize) | |
1267 | ERROR (gettext ("\ | |
1268 | section [%2d] '%s': hash chain reference %zu out of bounds\n"), | |
1269 | idx, section_name (ebl, idx), cnt - 2 - nbucket); | |
1270 | @@ -2311,6 +2320,8 @@ phdr[%d]: no note entries defined for th | |
1271 | return; | |
1272 | ||
1273 | char *notemem = gelf_rawchunk (ebl->elf, phdr->p_offset, phdr->p_filesz); | |
1274 | + if (notemem == NULL) | |
1275 | + return; | |
1276 | ||
1277 | /* ELF64 files often use note section entries in the 32-bit format. | |
1278 | The p_align field is set to 8 in case the 64-bit format is used. | |
1279 | ||
1280 | --- elfutils/src/strip.c | |
1281 | +++ elfutils/src/strip.c | |
1282 | @@ -400,6 +400,7 @@ handle_elf (int fd, Elf *elf, const char | |
1283 | Elf_Data debuglink_crc_data; | |
1284 | bool any_symtab_changes = false; | |
1285 | Elf_Data *shstrtab_data = NULL; | |
1286 | + size_t shdridx = 0; | |
1287 | ||
1288 | /* Create the full name of the file. */ | |
1289 | if (prefix != NULL) | |
1290 | @@ -531,6 +532,11 @@ handle_elf (int fd, Elf *elf, const char | |
1291 | goto fail_close; | |
1292 | } | |
1293 | ||
1294 | + if (shstrndx >= shnum) | |
1295 | + goto illformed; | |
1296 | + | |
1297 | +#define elf_assert(test) do { if (!(test)) goto illformed; } while (0) | |
1298 | + | |
1299 | /* Storage for section information. We leave room for two more | |
1300 | entries since we unconditionally create a section header string | |
1301 | table. Maybe some weird tool created an ELF file without one. | |
1302 | @@ -552,7 +558,7 @@ handle_elf (int fd, Elf *elf, const char | |
1303 | { | |
1304 | /* This should always be true (i.e., there should not be any | |
1305 | holes in the numbering). */ | |
1306 | - assert (elf_ndxscn (scn) == cnt); | |
1307 | + elf_assert (elf_ndxscn (scn) == cnt); | |
1308 | ||
1309 | shdr_info[cnt].scn = scn; | |
1310 | ||
1311 | @@ -565,6 +571,7 @@ handle_elf (int fd, Elf *elf, const char | |
1312 | shdr_info[cnt].shdr.sh_name); | |
1313 | if (shdr_info[cnt].name == NULL) | |
1314 | { | |
1315 | + illformed: | |
1316 | error (0, 0, gettext ("illformed file '%s'"), fname); | |
1317 | goto fail_close; | |
1318 | } | |
1319 | @@ -574,6 +581,8 @@ handle_elf (int fd, Elf *elf, const char | |
1320 | ||
1321 | /* Remember the shdr.sh_link value. */ | |
1322 | shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link; | |
1323 | + if (shdr_info[cnt].old_sh_link >= shnum) | |
1324 | + goto illformed; | |
1325 | ||
1326 | /* Sections in files other than relocatable object files which | |
1327 | are not loaded can be freely moved by us. In relocatable | |
1328 | @@ -586,7 +595,7 @@ handle_elf (int fd, Elf *elf, const char | |
1329 | appropriate reference. */ | |
1330 | if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX)) | |
1331 | { | |
1332 | - assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0); | |
1333 | + elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0); | |
1334 | shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt; | |
1335 | } | |
1336 | else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP)) | |
1337 | @@ -605,7 +614,12 @@ handle_elf (int fd, Elf *elf, const char | |
1338 | for (inner = 1; | |
1339 | inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); | |
1340 | ++inner) | |
1341 | - shdr_info[grpref[inner]].group_idx = cnt; | |
1342 | + { | |
1343 | + if (grpref[inner] < shnum) | |
1344 | + shdr_info[grpref[inner]].group_idx = cnt; | |
1345 | + else | |
1346 | + goto illformed; | |
1347 | + } | |
1348 | ||
1349 | if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0)) | |
1350 | /* If the section group contains only one element and this | |
1351 | @@ -616,7 +630,7 @@ handle_elf (int fd, Elf *elf, const char | |
1352 | } | |
1353 | else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)) | |
1354 | { | |
1355 | - assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0); | |
1356 | + elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0); | |
1357 | shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt; | |
1358 | } | |
1359 | ||
1360 | @@ -624,7 +638,7 @@ handle_elf (int fd, Elf *elf, const char | |
1361 | discarded right away. */ | |
1362 | if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0) | |
1363 | { | |
1364 | - assert (shdr_info[cnt].group_idx != 0); | |
1365 | + elf_assert (shdr_info[cnt].group_idx != 0); | |
1366 | ||
1367 | if (shdr_info[shdr_info[cnt].group_idx].idx == 0) | |
1368 | { | |
1369 | @@ -700,10 +714,14 @@ handle_elf (int fd, Elf *elf, const char | |
1370 | { | |
1371 | /* If a relocation section is marked as being removed make | |
1372 | sure the section it is relocating is removed, too. */ | |
1373 | - if ((shdr_info[cnt].shdr.sh_type == SHT_REL | |
1374 | - || shdr_info[cnt].shdr.sh_type == SHT_RELA) | |
1375 | - && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0) | |
1376 | - shdr_info[cnt].idx = 1; | |
1377 | + if (shdr_info[cnt].shdr.sh_type == SHT_REL | |
1378 | + || shdr_info[cnt].shdr.sh_type == SHT_RELA) | |
1379 | + { | |
1380 | + if (shdr_info[cnt].shdr.sh_info >= shnum) | |
1381 | + goto illformed; | |
1382 | + else if (shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0) | |
1383 | + shdr_info[cnt].idx = 1; | |
1384 | + } | |
1385 | } | |
1386 | ||
1387 | if (shdr_info[cnt].idx == 1) | |
1388 | @@ -733,7 +751,7 @@ handle_elf (int fd, Elf *elf, const char | |
1389 | if (shdr_info[cnt].symtab_idx != 0 | |
1390 | && shdr_info[shdr_info[cnt].symtab_idx].data == NULL) | |
1391 | { | |
1392 | - assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB); | |
1393 | + elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB); | |
1394 | ||
1395 | shdr_info[shdr_info[cnt].symtab_idx].data | |
1396 | = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, | |
1397 | @@ -773,6 +791,9 @@ handle_elf (int fd, Elf *elf, const char | |
1398 | else if (scnidx == SHN_XINDEX) | |
1399 | scnidx = xndx; | |
1400 | ||
1401 | + if (scnidx >= shnum) | |
1402 | + goto illformed; | |
1403 | + | |
1404 | if (shdr_info[scnidx].idx == 0) | |
1405 | { | |
1406 | /* Mark this section as used. */ | |
1407 | @@ -804,11 +825,15 @@ handle_elf (int fd, Elf *elf, const char | |
1408 | } | |
1409 | ||
1410 | /* Handle references through sh_info. */ | |
1411 | - if (SH_INFO_LINK_P (&shdr_info[cnt].shdr) | |
1412 | - && shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0) | |
1413 | + if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)) | |
1414 | { | |
1415 | - shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1; | |
1416 | - changes |= shdr_info[cnt].shdr.sh_info < cnt; | |
1417 | + if (shdr_info[cnt].shdr.sh_info >= shnum) | |
1418 | + goto illformed; | |
1419 | + else if ( shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0) | |
1420 | + { | |
1421 | + shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1; | |
1422 | + changes |= shdr_info[cnt].shdr.sh_info < cnt; | |
1423 | + } | |
1424 | } | |
1425 | ||
1426 | /* Mark the section as investigated. */ | |
1427 | @@ -911,7 +936,7 @@ handle_elf (int fd, Elf *elf, const char | |
1428 | error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"), | |
1429 | elf_errmsg (-1)); | |
1430 | ||
1431 | - assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); | |
1432 | + elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); | |
1433 | ||
1434 | /* Add this name to the section header string table. */ | |
1435 | shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0); | |
1436 | @@ -951,7 +976,7 @@ handle_elf (int fd, Elf *elf, const char | |
1437 | error (EXIT_FAILURE, 0, | |
1438 | gettext ("while create section header section: %s"), | |
1439 | elf_errmsg (-1)); | |
1440 | - assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); | |
1441 | + elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); | |
1442 | ||
1443 | shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn); | |
1444 | if (shdr_info[cnt].data == NULL) | |
1445 | @@ -982,7 +1007,7 @@ handle_elf (int fd, Elf *elf, const char | |
1446 | } | |
1447 | ||
1448 | /* Index of the section header table in the shdr_info array. */ | |
1449 | - size_t shdridx = cnt; | |
1450 | + shdridx = cnt; | |
1451 | ||
1452 | /* Add the section header string table section name. */ | |
1453 | shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10); | |
1454 | @@ -1007,7 +1032,7 @@ handle_elf (int fd, Elf *elf, const char | |
1455 | error (EXIT_FAILURE, 0, | |
1456 | gettext ("while create section header section: %s"), | |
1457 | elf_errmsg (-1)); | |
1458 | - assert (elf_ndxscn (shdr_info[cnt].newscn) == idx); | |
1459 | + elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx); | |
1460 | ||
1461 | /* Finalize the string table and fill in the correct indices in the | |
1462 | section headers. */ | |
1463 | @@ -1097,21 +1122,21 @@ handle_elf (int fd, Elf *elf, const char | |
1464 | shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, | |
1465 | NULL); | |
1466 | ||
1467 | - assert ((versiondata->d_size / sizeof (Elf32_Word)) | |
1468 | - >= shdr_info[cnt].data->d_size / elsize); | |
1469 | + elf_assert ((versiondata->d_size / sizeof (Elf32_Word)) | |
1470 | + >= shdr_info[cnt].data->d_size / elsize); | |
1471 | } | |
1472 | ||
1473 | if (shdr_info[cnt].version_idx != 0) | |
1474 | { | |
1475 | - assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM); | |
1476 | + elf_assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM); | |
1477 | /* This section has associated version | |
1478 | information. We have to modify that | |
1479 | information, too. */ | |
1480 | versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn, | |
1481 | NULL); | |
1482 | ||
1483 | - assert ((versiondata->d_size / sizeof (GElf_Versym)) | |
1484 | - >= shdr_info[cnt].data->d_size / elsize); | |
1485 | + elf_assert ((versiondata->d_size / sizeof (GElf_Versym)) | |
1486 | + >= shdr_info[cnt].data->d_size / elsize); | |
1487 | } | |
1488 | ||
1489 | shdr_info[cnt].newsymidx | |
1490 | @@ -1165,7 +1190,7 @@ handle_elf (int fd, Elf *elf, const char | |
1491 | sec = shdr_info[sym->st_shndx].idx; | |
1492 | else | |
1493 | { | |
1494 | - assert (shndxdata != NULL); | |
1495 | + elf_assert (shndxdata != NULL); | |
1496 | ||
1497 | sec = shdr_info[xshndx].idx; | |
1498 | } | |
1499 | @@ -1186,7 +1211,7 @@ handle_elf (int fd, Elf *elf, const char | |
1500 | nxshndx = sec; | |
1501 | } | |
1502 | ||
1503 | - assert (sec < SHN_LORESERVE || shndxdata != NULL); | |
1504 | + elf_assert (sec < SHN_LORESERVE || shndxdata != NULL); | |
1505 | ||
1506 | if ((inner != destidx || nshndx != sym->st_shndx | |
1507 | || (shndxdata != NULL && nxshndx != xshndx)) | |
1508 | @@ -1209,7 +1234,7 @@ handle_elf (int fd, Elf *elf, const char | |
1509 | else | |
1510 | /* This is a section symbol for a section which has | |
1511 | been removed. */ | |
1512 | - assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION); | |
1513 | + elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION); | |
1514 | } | |
1515 | ||
1516 | if (destidx != inner) | |
1517 | @@ -1373,11 +1398,11 @@ handle_elf (int fd, Elf *elf, const char | |
1518 | { | |
1519 | GElf_Sym sym_mem; | |
1520 | GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); | |
1521 | - assert (sym != NULL); | |
1522 | + elf_assert (sym != NULL); | |
1523 | ||
1524 | const char *name = elf_strptr (elf, strshndx, | |
1525 | sym->st_name); | |
1526 | - assert (name != NULL); | |
1527 | + elf_assert (name != NULL); | |
1528 | size_t hidx = elf_hash (name) % nbucket; | |
1529 | ||
1530 | if (bucket[hidx] == 0) | |
1531 | @@ -1396,8 +1421,8 @@ handle_elf (int fd, Elf *elf, const char | |
1532 | else | |
1533 | { | |
1534 | /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */ | |
1535 | - assert (shdr_info[cnt].shdr.sh_entsize | |
1536 | - == sizeof (Elf64_Xword)); | |
1537 | + elf_assert (shdr_info[cnt].shdr.sh_entsize | |
1538 | + == sizeof (Elf64_Xword)); | |
1539 | ||
1540 | Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf; | |
1541 | ||
1542 | @@ -1430,11 +1455,11 @@ handle_elf (int fd, Elf *elf, const char | |
1543 | { | |
1544 | GElf_Sym sym_mem; | |
1545 | GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); | |
1546 | - assert (sym != NULL); | |
1547 | + elf_assert (sym != NULL); | |
1548 | ||
1549 | const char *name = elf_strptr (elf, strshndx, | |
1550 | sym->st_name); | |
1551 | - assert (name != NULL); | |
1552 | + elf_assert (name != NULL); | |
1553 | size_t hidx = elf_hash (name) % nbucket; | |
1554 | ||
1555 | if (bucket[hidx] == 0) | |
1556 | --- elfutils/src/readelf.c | |
1557 | +++ elfutils/src/readelf.c | |
1558 | @@ -947,6 +947,7 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G | |
1559 | GElf_Shdr *symshdr; | |
1560 | Elf_Data *symdata; | |
1561 | GElf_Sym sym_mem; | |
1562 | + GElf_Sym *sym; | |
1563 | size_t cnt; | |
1564 | size_t shstrndx; | |
1565 | ||
1566 | @@ -966,6 +967,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G | |
1567 | error (EXIT_FAILURE, 0, | |
1568 | gettext ("cannot get section header string table index")); | |
1569 | ||
1570 | + sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem); | |
1571 | + | |
1572 | grpref = (Elf32_Word *) data->d_buf; | |
1573 | ||
1574 | printf ((grpref[0] & GRP_COMDAT) | |
1575 | @@ -980,8 +983,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G | |
1576 | data->d_size / sizeof (Elf32_Word) - 1), | |
1577 | elf_ndxscn (scn), | |
1578 | elf_strptr (ebl->elf, shstrndx, shdr->sh_name), | |
1579 | - elf_strptr (ebl->elf, symshdr->sh_link, | |
1580 | - gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name) | |
1581 | + (sym == NULL ? NULL | |
1582 | + : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) | |
1583 | ?: gettext ("<INVALID SYMBOL>"), | |
1584 | data->d_size / sizeof (Elf32_Word) - 1); | |
1585 | ||
1586 | @@ -1135,7 +1138,8 @@ static void | |
1587 | handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) | |
1588 | { | |
1589 | int class = gelf_getclass (ebl->elf); | |
1590 | - GElf_Shdr glink; | |
1591 | + GElf_Shdr glink_mem; | |
1592 | + GElf_Shdr *glink; | |
1593 | Elf_Data *data; | |
1594 | size_t cnt; | |
1595 | size_t shstrndx; | |
1596 | @@ -1150,6 +1154,11 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, | |
1597 | error (EXIT_FAILURE, 0, | |
1598 | gettext ("cannot get section header string table index")); | |
1599 | ||
1600 | + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); | |
1601 | + if (glink == NULL) | |
1602 | + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"), | |
1603 | + elf_ndxscn (scn)); | |
1604 | + | |
1605 | printf (ngettext ("\ | |
1606 | \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", | |
1607 | "\ | |
1608 | @@ -1159,9 +1168,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, | |
1609 | class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, | |
1610 | shdr->sh_offset, | |
1611 | (int) shdr->sh_link, | |
1612 | - elf_strptr (ebl->elf, shstrndx, | |
1613 | - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), | |
1614 | - &glink)->sh_name)); | |
1615 | + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); | |
1616 | fputs_unlocked (gettext (" Type Value\n"), stdout); | |
1617 | ||
1618 | for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) | |
1619 | @@ -1656,7 +1663,8 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G | |
1620 | unsigned int cnt; | |
1621 | Elf32_Word verneed_stridx = 0; | |
1622 | Elf32_Word verdef_stridx = 0; | |
1623 | - GElf_Shdr glink; | |
1624 | + GElf_Shdr glink_mem; | |
1625 | + GElf_Shdr *glink; | |
1626 | size_t shstrndx; | |
1627 | ||
1628 | /* Get the data of the section. */ | |
1629 | @@ -1701,6 +1709,11 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G | |
1630 | error (EXIT_FAILURE, 0, | |
1631 | gettext ("cannot get section header string table index")); | |
1632 | ||
1633 | + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); | |
1634 | + if (glink == NULL) | |
1635 | + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"), | |
1636 | + elf_ndxscn (scn)); | |
1637 | + | |
1638 | /* Now we can compute the number of entries in the section. */ | |
1639 | nsyms = data->d_size / (class == ELFCLASS32 | |
1640 | ? sizeof (Elf32_Sym) : sizeof (Elf64_Sym)); | |
1641 | @@ -1715,9 +1728,7 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G | |
1642 | shdr->sh_info), | |
1643 | (unsigned long int) shdr->sh_info, | |
1644 | (unsigned int) shdr->sh_link, | |
1645 | - elf_strptr (ebl->elf, shstrndx, | |
1646 | - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), | |
1647 | - &glink)->sh_name)); | |
1648 | + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); | |
1649 | ||
1650 | fputs_unlocked (class == ELFCLASS32 | |
1651 | ? gettext ("\ | |
1652 | @@ -1945,7 +1956,8 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, | |
1653 | { | |
1654 | Elf_Data *data; | |
1655 | int class = gelf_getclass (ebl->elf); | |
1656 | - GElf_Shdr glink; | |
1657 | + GElf_Shdr glink_mem; | |
1658 | + GElf_Shdr *glink; | |
1659 | int cnt; | |
1660 | unsigned int offset; | |
1661 | size_t shstrndx; | |
1662 | @@ -1960,6 +1972,11 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, | |
1663 | error (EXIT_FAILURE, 0, | |
1664 | gettext ("cannot get section header string table index")); | |
1665 | ||
1666 | + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); | |
1667 | + if (glink == NULL) | |
1668 | + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"), | |
1669 | + elf_ndxscn (scn)); | |
1670 | + | |
1671 | printf (ngettext ("\ | |
1672 | \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", | |
1673 | "\ | |
1674 | @@ -1970,9 +1987,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, | |
1675 | class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, | |
1676 | shdr->sh_offset, | |
1677 | (unsigned int) shdr->sh_link, | |
1678 | - elf_strptr (ebl->elf, shstrndx, | |
1679 | - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), | |
1680 | - &glink)->sh_name)); | |
1681 | + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); | |
1682 | ||
1683 | offset = 0; | |
1684 | for (cnt = shdr->sh_info; --cnt >= 0; ) | |
1685 | @@ -2022,7 +2037,8 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G | |
1686 | { | |
1687 | Elf_Data *data; | |
1688 | int class = gelf_getclass (ebl->elf); | |
1689 | - GElf_Shdr glink; | |
1690 | + GElf_Shdr glink_mem; | |
1691 | + GElf_Shdr *glink; | |
1692 | int cnt; | |
1693 | unsigned int offset; | |
1694 | size_t shstrndx; | |
1695 | @@ -2037,6 +2053,11 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G | |
1696 | error (EXIT_FAILURE, 0, | |
1697 | gettext ("cannot get section header string table index")); | |
1698 | ||
1699 | + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); | |
1700 | + if (glink == NULL) | |
1701 | + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"), | |
1702 | + elf_ndxscn (scn)); | |
1703 | + | |
1704 | printf (ngettext ("\ | |
1705 | \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", | |
1706 | "\ | |
1707 | @@ -2048,9 +2069,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G | |
1708 | class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, | |
1709 | shdr->sh_offset, | |
1710 | (unsigned int) shdr->sh_link, | |
1711 | - elf_strptr (ebl->elf, shstrndx, | |
1712 | - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), | |
1713 | - &glink)->sh_name)); | |
1714 | + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); | |
1715 | ||
1716 | offset = 0; | |
1717 | for (cnt = shdr->sh_info; --cnt >= 0; ) | |
1718 | @@ -2106,7 +2125,8 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G | |
1719 | Elf_Data *data; | |
1720 | int class = gelf_getclass (ebl->elf); | |
1721 | Elf_Scn *verscn; | |
1722 | - GElf_Shdr glink; | |
1723 | + GElf_Shdr glink_mem; | |
1724 | + GElf_Shdr *glink; | |
1725 | Elf_Scn *defscn; | |
1726 | Elf_Scn *needscn; | |
1727 | const char **vername; | |
1728 | @@ -2125,6 +2145,11 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G | |
1729 | error (EXIT_FAILURE, 0, | |
1730 | gettext ("cannot get section header string table index")); | |
1731 | ||
1732 | + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); | |
1733 | + if (glink == NULL) | |
1734 | + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"), | |
1735 | + elf_ndxscn (scn)); | |
1736 | + | |
1737 | /* We have to find the version definition section and extract the | |
1738 | version names. */ | |
1739 | defscn = NULL; | |
1740 | @@ -2347,9 +2372,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G | |
1741 | class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, | |
1742 | shdr->sh_offset, | |
1743 | (unsigned int) shdr->sh_link, | |
1744 | - elf_strptr (ebl->elf, shstrndx, | |
1745 | - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), | |
1746 | - &glink)->sh_name)); | |
1747 | + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); | |
1748 | ||
1749 | /* Now we can finally look at the actual contents of this section. */ | |
1750 | for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) | |
1751 | @@ -2425,7 +2448,8 @@ handle_hash (Ebl *ebl) | |
1752 | Elf32_Word maxlength = 0; | |
1753 | Elf32_Word nsyms = 0; | |
1754 | uint64_t nzero_counts = 0; | |
1755 | - GElf_Shdr glink; | |
1756 | + GElf_Shdr glink_mem; | |
1757 | + GElf_Shdr *glink; | |
1758 | ||
1759 | if (data == NULL) | |
1760 | { | |
1761 | @@ -2434,6 +2458,16 @@ handle_hash (Ebl *ebl) | |
1762 | continue; | |
1763 | } | |
1764 | ||
1765 | + | |
1766 | + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), | |
1767 | + &glink_mem); | |
1768 | + if (glink == NULL) | |
1769 | + { | |
1770 | + error (0, 0, gettext ("invalid sh_link value in section %Zu"), | |
1771 | + elf_ndxscn (scn)); | |
1772 | + continue; | |
1773 | + } | |
1774 | + | |
1775 | nbucket = ((Elf32_Word *) data->d_buf)[0]; | |
1776 | nchain = ((Elf32_Word *) data->d_buf)[1]; | |
1777 | bucket = &((Elf32_Word *) data->d_buf)[2]; | |
1778 | @@ -2451,10 +2485,7 @@ handle_hash (Ebl *ebl) | |
1779 | shdr->sh_addr, | |
1780 | shdr->sh_offset, | |
1781 | (unsigned int) shdr->sh_link, | |
1782 | - elf_strptr (ebl->elf, shstrndx, | |
1783 | - gelf_getshdr (elf_getscn (ebl->elf, | |
1784 | - shdr->sh_link), | |
1785 | - &glink)->sh_name)); | |
1786 | + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); | |
1787 | ||
1788 | lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); | |
1789 |