]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl: Skip segment that starts past contents_size in elf-from-memory
authorSayed Kaif <skaif@digiscrypt.com>
Wed, 17 Jun 2026 10:31:45 +0000 (16:01 +0530)
committerMark Wielaard <mark@klomp.org>
Fri, 19 Jun 2026 12:28:39 +0000 (14:28 +0200)
When rebuilding an ELF from process memory, segments_end used the last
PT_LOAD segment's end rather than the largest, so a later smaller
segment could shrink contents_size below an earlier segment's start,
underflowing end - start into a huge length and overflowing the heap
buffer. Skip any segment that starts past contents_size, matching the
guard already used in dwfl_segment_report_module.

* libdwfl/elf-from-memory.c (elf_from_remote_memory): Skip
out-of-range segment.

Signed-off-by: Sayed Kaif <skaif@digiscrypt.com>
libdwfl/elf-from-memory.c

index e9b330fd66df284cb9cd980fc5920c604e4c2c1e..14b2f5c8a7192aa0be57477b6af0587765ea7ec5 100644 (file)
@@ -304,6 +304,14 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
 
       GElf_Off start = offset & -pagesize;
       GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
+      /* The final contents_size is the trimmed last segment's end, which
+        may be smaller than an earlier segment's start (segments_end above
+        tracks the last PT_LOAD, not the maximum).  Skip any segment that
+        falls entirely past it: otherwise buffer + start would be out of
+        bounds and end - start would underflow into a huge read length.
+        Mirrors the file_trimmed_end check in dwfl_segment_report_module.  */
+      if (start >= (GElf_Off) contents_size)
+        continue;
       if (end > (GElf_Off) contents_size)
         end = contents_size;
       nread = (*read_memory) (arg, buffer + start,