[binutils-gdb] readelf PT_PHDR check

Alan Modra amodra@sourceware.org
Fri Oct 25 04:49:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c0c121b01c8a9408ae22ee9007dd0273f4c8d0be

commit c0c121b01c8a9408ae22ee9007dd0273f4c8d0be
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Oct 25 12:21:35 2019 +1030

    readelf PT_PHDR check
    
    When PT_PHDR isn't covered by a PT_LOAD header, p_vaddr in PT_PHDR
    isn't valid but the value might just pass a vaddr test.  So test
    p_offset as well.
    
    	* readelf.c (process_program_headers): Check PT_PHDR p_offset
    	as well as p_vaddr.  Use p_filesz, not p_memsz, in vaddr test.

Diff:
---
 binutils/ChangeLog |  5 +++++
 binutils/readelf.c | 16 +++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 74a223b..f1b3c0e 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2019-10-25  Alan Modra  <amodra@gmail.com>
+
+	* readelf.c (process_program_headers): Check PT_PHDR p_offset
+	as well as p_vaddr.  Use p_filesz, not p_memsz, in vaddr test.
+
 2019-10-21  Alan Modra  <amodra@gmail.com>
 
 	PR 452
diff --git a/binutils/readelf.c b/binutils/readelf.c
index de77237..370bc4c 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -5262,11 +5262,17 @@ process_program_headers (Filedata * filedata)
 	      unsigned int j;
 
 	      for (j = 1; j < filedata->file_header.e_phnum; j++)
-		if (filedata->program_headers[j].p_vaddr <= segment->p_vaddr
-		    && (filedata->program_headers[j].p_vaddr
-			+ filedata->program_headers[j].p_memsz)
-		    >= (segment->p_vaddr + segment->p_filesz))
-		  break;
+		{
+		  Elf_Internal_Phdr *load = filedata->program_headers + j;
+		  if (load->p_type == PT_LOAD
+		      && load->p_offset <= segment->p_offset
+		      && (load->p_offset + load->p_filesz
+			  >= segment->p_offset + segment->p_filesz)
+		      && load->p_vaddr <= segment->p_vaddr
+		      && (load->p_vaddr + load->p_filesz
+			  >= segment->p_vaddr + segment->p_filesz))
+		    break;
+		}
 	      if (j == filedata->file_header.e_phnum)
 		error (_("the PHDR segment is not covered by a LOAD segment\n"));
 	    }



More information about the Binutils-cvs mailing list