readelf PT_PHDR check

Message ID 20191025031208.GA22462@bubble.grove.modra.org
State New
Headers show
Series
  • readelf PT_PHDR check
Related show

Commit Message

Alan Modra Oct. 25, 2019, 3:12 a.m.
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.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/binutils/readelf.c b/binutils/readelf.c
index de77237e0e..370bc4c1b7 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"));
 	    }