/[gentoo-projects]/pax-utils/scanelf.c
Gentoo

Diff of /pax-utils/scanelf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.276 Revision 1.277
1/* 1/*
2 * Copyright 2003-2012 Gentoo Foundation 2 * Copyright 2003-2012 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2 3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.276 2015/02/28 22:57:40 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.277 2015/02/28 22:59:34 vapier Exp $
5 * 5 *
6 * Copyright 2003-2012 Ned Ludd - <solar@gentoo.org> 6 * Copyright 2003-2012 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org> 7 * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org>
8 */ 8 */
9 9
10static const char rcsid[] = "$Id: scanelf.c,v 1.276 2015/02/28 22:57:40 vapier Exp $"; 10static const char rcsid[] = "$Id: scanelf.c,v 1.277 2015/02/28 22:59:34 vapier Exp $";
11const char argv0[] = "scanelf"; 11const char argv0[] = "scanelf";
12 12
13#include "paxinc.h" 13#include "paxinc.h"
14 14
15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+') 15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+')
273 \ 273 \
274 /* calc offset into the ELF by finding the load addr of the syms */ \ 274 /* calc offset into the ELF by finding the load addr of the syms */ \
275 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 275 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
276 Elf ## B ## _Addr vaddr = EGET(phdr[i].p_vaddr); \ 276 Elf ## B ## _Addr vaddr = EGET(phdr[i].p_vaddr); \
277 Elf ## B ## _Addr filesz = EGET(phdr[i].p_filesz); \ 277 Elf ## B ## _Addr filesz = EGET(phdr[i].p_filesz); \
278 offset = EGET(phdr[i].p_offset); \ 278 Elf ## B ## _Off hash_offset = offset + (vhash - vaddr); \
279 \ 279 \
280 if (EGET(phdr[i].p_type) != PT_LOAD) \ 280 if (EGET(phdr[i].p_type) != PT_LOAD) \
281 continue; \ 281 continue; \
282 \ 282 \
283 offset = EGET(phdr[i].p_offset); \
284 if (offset >= (uint64_t)elf->len) \
285 goto corrupt_hash; \
286 if (filesz >= (uint64_t)elf->len) \
287 goto corrupt_hash; \
288 if (hash_offset + (sizeof(Elf32_Word) * 4) > (uint64_t)elf->len) \
289 goto corrupt_hash; \
290 \
283 if (vhash >= vaddr && vhash < vaddr + filesz) { \ 291 if (vhash >= vaddr && vhash < vaddr + filesz) { \
284 /* Scan the hash table to see how many entries we have */ \ 292 /* Scan the hash table to see how many entries we have */ \
285 Elf32_Word max_sym_idx = 0; \ 293 Elf32_Word max_sym_idx = 0; \
286 Elf32_Word *hashtbl = elf->vdata + offset + (vhash - vaddr); \ 294 Elf32_Word *hashtbl = elf->vdata + hash_offset; \
287 Elf32_Word b, nbuckets = EGET(hashtbl[0]); \ 295 Elf32_Word b, nbuckets = EGET(hashtbl[0]); \
288 Elf32_Word nchains = EGET(hashtbl[1]); \ 296 Elf32_Word nchains = EGET(hashtbl[1]); \
289 Elf32_Word *buckets = &hashtbl[2]; \ 297 Elf32_Word *buckets = &hashtbl[2]; \
290 Elf32_Word *chains = &buckets[nbuckets]; \ 298 Elf32_Word *chains = &buckets[nbuckets]; \
291 Elf32_Word sym_idx; \ 299 Elf32_Word sym_idx; \
292 Elf32_Word chained; \ 300 Elf32_Word chained; \
301 \
302 if (hash_offset >= (uint64_t)elf->len) \
303 goto corrupt_hash; \
304 if (nbuckets >= UINT32_MAX / 4) \
305 goto corrupt_hash; \
306 if (nchains >= UINT32_MAX / 4) \
307 goto corrupt_hash; \
308 if (nbuckets * 4 > elf->len - offset) \
309 goto corrupt_hash; \
310 if (nchains * 4 > elf->len - offset) \
311 goto corrupt_hash; \
293 \ 312 \
294 for (b = 0; b < nbuckets; ++b) { \ 313 for (b = 0; b < nbuckets; ++b) { \
295 if (!buckets[b]) \ 314 if (!buckets[b]) \
296 continue; \ 315 continue; \
297 for (sym_idx = buckets[b], chained = 0; \ 316 for (sym_idx = buckets[b], chained = 0; \
298 sym_idx < nchains && sym_idx && chained <= nchains; \ 317 sym_idx < nchains && sym_idx && chained <= nchains; \
299 sym_idx = chains[sym_idx], ++chained) { \ 318 sym_idx = chains[sym_idx], ++chained) { \
300 if (max_sym_idx < sym_idx) \ 319 if (max_sym_idx < sym_idx) \
301 max_sym_idx = sym_idx; \ 320 max_sym_idx = sym_idx; \
302 } \ 321 } \
303 if (chained > nchains) { \ 322 if (chained > nchains) \
304 warnf("corrupt ELF bucket"); \ 323 goto corrupt_hash; \
305 break; \
306 } \
307 } \ 324 } \
308 ESET(sym_shdr.sh_size, sym_shdr.sh_entsize * max_sym_idx); \ 325 ESET(sym_shdr.sh_size, sym_shdr.sh_entsize * max_sym_idx); \
309 } \ 326 } \
310 \ 327 \
311 if (vsym >= vaddr && vsym < vaddr + filesz) { \ 328 if (vsym >= vaddr && vsym < vaddr + filesz) { \
319 } \ 336 } \
320 } \ 337 } \
321 } 338 }
322 GET_SYMTABS_DT(32) 339 GET_SYMTABS_DT(32)
323 GET_SYMTABS_DT(64) 340 GET_SYMTABS_DT(64)
341 return;
342
343 corrupt_hash:
344 warn("%s: ELF hash table is corrupt", elf->filename);
324} 345}
325 346
326static char *scanelf_file_pax(elfobj *elf, char *found_pax) 347static char *scanelf_file_pax(elfobj *elf, char *found_pax)
327{ 348{
328 static char ret[7]; 349 static char ret[7];
438 ++shown; \ 459 ++shown; \
439 } \ 460 } \
440 } else if (elf->shdr != NULL) { \ 461 } else if (elf->shdr != NULL) { \
441 /* no program headers which means this is prob an object file */ \ 462 /* no program headers which means this is prob an object file */ \
442 Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \ 463 Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \
464 uint16_t shstrndx = EGET(ehdr->e_shstrndx); \
443 Elf ## B ## _Shdr *strtbl = shdr + EGET(ehdr->e_shstrndx); \ 465 Elf ## B ## _Shdr *strtbl = shdr + shstrndx; \
444 if ((void*)strtbl > elf->data_end) \ 466 if (shstrndx >= elf->len - sizeof(*strtbl) || !VALID_SHDR(elf, strtbl)) \
445 goto skip_this_shdr##B; \ 467 goto skip_this_shdr##B; \
446 /* let's flag -w/+x object files since the final ELF will most likely \ 468 /* let's flag -w/+x object files since the final ELF will most likely \
447 * need write access to the stack (who doesn't !?). so the combined \ 469 * need write access to the stack (who doesn't !?). so the combined \
448 * output will bring in +w automatically and that's bad. \ 470 * output will bring in +w automatically and that's bad. \
449 */ \ 471 */ \
1407 if (!VALID_SHDR(elf, symtab) || !VALID_SHDR(elf, strtab)) \ 1429 if (!VALID_SHDR(elf, symtab) || !VALID_SHDR(elf, strtab)) \
1408 goto break_out; \ 1430 goto break_out; \
1409 if (cnt) \ 1431 if (cnt) \
1410 cnt = EGET(symtab->sh_size) / cnt; \ 1432 cnt = EGET(symtab->sh_size) / cnt; \
1411 for (i = 0; i < cnt; ++i) { \ 1433 for (i = 0; i < cnt; ++i) { \
1412 if ((void*)sym > elf->data_end) { \ 1434 if ((void *)sym >= elf->data_end - sizeof(*sym)) \
1413 warnf("%s: corrupt ELF symbols - aborting", elf->filename); \
1414 goto break_out; \ 1435 goto break_out; \
1415 } \
1416 if (sym->st_name) { \ 1436 if (sym->st_name) { \
1417 /* make sure the symbol name is in acceptable memory range */ \ 1437 /* make sure the symbol name is in acceptable memory range */ \
1418 symname = elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name); \ 1438 symname = elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name); \
1419 if ((void*)symname > elf->data_end) { \ 1439 if (EGET(sym->st_name) >= (uint64_t)elf->len || \
1420 warnf("%s: corrupt ELF symbols", elf->filename); \ 1440 EGET(strtab->sh_offset) + EGET(sym->st_name) >= (uint64_t)elf->len || \
1421 ++sym; \ 1441 !memchr(symname, 0, elf->len - EGET(strtab->sh_offset) + EGET(sym->st_name))) \
1422 continue; \ 1442 goto break_out; \
1423 } \
1424 scanelf_match_symname(elf, found_sym, \ 1443 scanelf_match_symname(elf, found_sym, \
1425 &ret, &ret_len, symname, \ 1444 &ret, &ret_len, symname, \
1426 ELF##B##_ST_TYPE(EGET(sym->st_info)), \ 1445 ELF##B##_ST_TYPE(EGET(sym->st_info)), \
1427 ELF##B##_ST_BIND(EGET(sym->st_info)), \ 1446 ELF##B##_ST_BIND(EGET(sym->st_info)), \
1428 ELF##B##_ST_VISIBILITY(EGET(sym->st_other)), \ 1447 ELF##B##_ST_VISIBILITY(EGET(sym->st_other)), \
1429 EGET(sym->st_shndx), \ 1448 EGET(sym->st_shndx), \
1430 /* st_size can be 64bit, but no one is really that big, so screw em */ \ 1449 /* st_size can be 64bit, but no one is really that big, so screw em */ \
1431 EGET(sym->st_size)); \ 1450 EGET(sym->st_size)); \
1432 } \ 1451 } \
1433 ++sym; \ 1452 ++sym; \
1434 } \ 1453 } \
1435 } 1454 }
1436 FIND_SYM(32) 1455 FIND_SYM(32)
1437 FIND_SYM(64) 1456 FIND_SYM(64)
1438 } 1457 }
1439 1458
1440break_out:
1441 if (be_wewy_wewy_quiet) return NULL; 1459 if (be_wewy_wewy_quiet) return NULL;
1442 1460
1443 if (*find_sym != '*' && *found_sym) 1461 if (*find_sym != '*' && *found_sym)
1444 return ret; 1462 return ret;
1445 if (be_quiet) 1463 if (be_quiet)
1446 return NULL; 1464 return NULL;
1447 else 1465 else
1448 return " - "; 1466 return " - ";
1467
1468 break_out:
1469 warnf("%s: corrupt ELF symbols", elf->filename);
1470 return NULL;
1449} 1471}
1450 1472
1451static const char *scanelf_file_sections(elfobj *elf, char *found_section) 1473static const char *scanelf_file_sections(elfobj *elf, char *found_section)
1452{ 1474{
1453 if (!find_section) 1475 if (!find_section)

Legend:
Removed from v.1.276  
changed lines
  Added in v.1.277

  ViewVC Help
Powered by ViewVC 1.1.20