diff options
author | Ulrich Drepper <[email protected]> | 2009-01-16 21:11:49 -0800 |
---|---|---|
committer | Ulrich Drepper <[email protected]> | 2009-01-16 21:11:49 -0800 |
commit | 3a52c7a528e41cc28e69e68ef817f0b2d7f130e5 (patch) | |
tree | 3b90be96c4b183b50479b32b7b6dcce13819c42e | |
parent | 05d2b20ec250a51de74066a203b516f11bc30d89 (diff) |
Implement check for PT_GNU_EH_FRAME program header check.
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | src/ChangeLog | 4 | ||||
-rw-r--r-- | src/elflint.c | 37 |
4 files changed, 45 insertions, 2 deletions
@@ -5,6 +5,8 @@ libcpu: Add Intel SSE4 disassembler support readelf: Implement call frame information and exception handling dumping. Add -e option. Enable it implicitly for -a. +elflint: Check PT_GNU_EH_FRAME program header entry. + libdwfl: Support automatic gzip/bzip2 decompression of ELF files. Version 0.138: @@ -1,7 +1,7 @@ ToDo list for elfutils -*-outline-*- ---------------------- -Time-stamp: <2009-01-01 16:56:38 drepper> +Time-stamp: <2009-01-16 20:55:06 drepper> * mkinstalldirs @@ -118,6 +118,8 @@ Time-stamp: <2009-01-01 16:56:38 drepper> check TLS relocation depencies + Check content of .eh_frame_hdr, .eh_frame, .gcc_except_table + *** for x86 check that R_386_TLS_GD is followed by R_386_PLT32 for __tls_get_addr diff --git a/src/ChangeLog b/src/ChangeLog index ab13810e..4a9b6316 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,9 @@ 2009-01-16 Ulrich Drepper <[email protected]> + * elflint.c (check_program_header): Check that PT_GNU_EH_FRAME entry + matches .eh_frame_hdr section, if it is available. Also check that + the segment is allocated, not writable, not executable. + * readelf.c: Add -e option. Dump exception and unwind related sections. Add -e to -a. (print_encoding_base): Handle DW_EH_PE_omit. diff --git a/src/elflint.c b/src/elflint.c index 23b0f496..35368a5e 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -4132,7 +4132,7 @@ more than one GNU_RELRO entry in program header\n")); if ((phdr2->p_flags & PF_W) == 0) ERROR (gettext ("\ loadable segment GNU_RELRO applies to is not writable\n")); - if ((phdr2->p_flags &~ PF_W) != (phdr->p_flags &~ PF_W)) + if ((phdr2->p_flags & ~PF_W) != (phdr->p_flags & ~PF_W)) ERROR (gettext ("\ loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"), cnt, inner); @@ -4173,6 +4173,41 @@ loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"), ERROR (gettext ("\ program header offset in ELF header and PHDR entry do not match")); } + else if (phdr->p_type == PT_GNU_EH_FRAME) + { + /* If there is an .eh_frame_hdr section it must be + referenced by this program header entry. */ + Elf_Scn *scn = NULL; + while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr != NULL && shdr->sh_type == SHT_PROGBITS + && ! strcmp (".eh_frame_hdr", + elf_strptr (ebl->elf, shstrndx, shdr->sh_name))) + { + if (phdr->p_offset != shdr->sh_offset) + ERROR (gettext ("\ +call frame search table reference in program header has wrong offset\n")); + if (phdr->p_memsz != shdr->sh_size) + ERROR (gettext ("\ +call frame search table size mismatch in program and section header\n")); + break; + } + } + + /* The section must be allocated and not be writable and + executable. */ + if ((phdr->p_flags & PF_R) == 0) + ERROR (gettext ("\ +call frame search table must be allocated\n")); + if ((phdr->p_flags & PF_W) != 0) + ERROR (gettext ("\ +call frame search table must not be writable\n")); + if ((phdr->p_flags & PF_X) != 0) + ERROR (gettext ("\ +call frame search table must not be executable\n")); + } if (phdr->p_filesz > phdr->p_memsz && (phdr->p_memsz != 0 || phdr->p_type != PT_NOTE)) |