summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2014-03-03 15:07:31 +0100
committerMark Wielaard <[email protected]>2014-03-17 11:08:09 +0100
commitdd64d4a9268b822b035f8c59c2b8f55a65f80819 (patch)
tree47015d8c7f0c7e14febba7ac27047c28ee02cda6
parent51fff30ac9d9eb245e7df8eb5c07658d04d6ad45 (diff)
libdwfl: elf_from_remote_memory only trust shdrs of last file-only segment.
If the last PT_LOAD segment that contains the whole shdrs also extends the segment in memory beyond the end of file the program might be reusing the memory space that we expect the shdrs to be in. Don't trust the shdrs are valid in that case. Signed-off-by: Mark Wielaard <[email protected]>
-rw-r--r--libdwfl/ChangeLog7
-rw-r--r--libdwfl/elf-from-memory.c17
2 files changed, 19 insertions, 5 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 85307875..b6a9161e 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,10 @@
+2014-03-03 Mark Wielaard <[email protected]>
+
+ * elf-from-memory.c (elf_from_remote_memory): Keep track of
+ segments_end_mem. Pass memsz to first handle_segment pass. Only
+ extend contents_size and use shdrs if only file bits are in
+ segment.
+
2014-03-11 Josh Stone <[email protected]>
* dwfl_module_getdwarf.c (open_elf): Only explicitly set
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c
index 602614b8..df9fbe69 100644
--- a/libdwfl/elf-from-memory.c
+++ b/libdwfl/elf-from-memory.c
@@ -196,6 +196,7 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
/* Scan for PT_LOAD segments to find the total size of the file image. */
size_t contents_size = 0;
GElf_Off segments_end = 0;
+ GElf_Off segments_end_mem = 0;
GElf_Addr loadbase = ehdr_vma;
bool found_base = false;
switch (ehdr.e32.e_ident[EI_CLASS])
@@ -205,7 +206,8 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
found_base yet). Returns true if sanity checking failed,
false otherwise. */
inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
- GElf_Xword filesz, GElf_Xword palign)
+ GElf_Xword filesz, GElf_Xword memsz,
+ GElf_Xword palign)
{
/* Sanity check the alignment requirements. */
if ((palign & (pagesize - 1)) != 0
@@ -225,6 +227,7 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
}
segments_end = offset + filesz;
+ segments_end_mem = offset + memsz;
return false;
}
@@ -235,7 +238,8 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
for (uint_fast16_t i = 0; i < phnum; ++i)
if (phdrs.p32[i].p_type == PT_LOAD)
if (handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
- phdrs.p32[i].p_filesz, phdrs.p32[i].p_align))
+ phdrs.p32[i].p_filesz, phdrs.p32[i].p_memsz,
+ phdrs.p32[i].p_align))
goto bad_elf;
break;
@@ -246,7 +250,8 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
for (uint_fast16_t i = 0; i < phnum; ++i)
if (phdrs.p64[i].p_type == PT_LOAD)
if (handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
- phdrs.p64[i].p_filesz, phdrs.p64[i].p_align))
+ phdrs.p64[i].p_filesz, phdrs.p64[i].p_memsz,
+ phdrs.p64[i].p_align))
goto bad_elf;
break;
@@ -257,9 +262,11 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
/* Trim the last segment so we don't bother with zeros in the last page
that are off the end of the file. However, if the extra bit in that
- page includes the section headers, keep them. */
+ page includes the section headers and the memory isn't extended (which
+ might indicate it will have been reused otherwise), keep them. */
if ((GElf_Off) contents_size > segments_end
- && (GElf_Off) contents_size >= shdrs_end)
+ && (GElf_Off) contents_size >= shdrs_end
+ && segments_end == segments_end_mem)
{
contents_size = segments_end;
if ((GElf_Off) contents_size < shdrs_end)