svn commit: r310137 - head/contrib/elftoolchain/libelf

Conrad E. Meyer cem at FreeBSD.org
Fri Dec 16 01:42:52 UTC 2016


Author: cem
Date: Fri Dec 16 01:42:51 2016
New Revision: 310137
URL: https://svnweb.freebsd.org/changeset/base/310137

Log:
  gelf_getphdr: Allow extended indices
  
  Needed for 'readelf -l' of extended phnum files.  (Parity with GNU
  binutils.)
  
  Reviewed by:	no one, unfortunately
  Sponsored by:	Dell EMC Isilon
  Differential Revision:	https://reviews.freebsd.org/D8703

Modified:
  head/contrib/elftoolchain/libelf/gelf_phdr.c

Modified: head/contrib/elftoolchain/libelf/gelf_phdr.c
==============================================================================
--- head/contrib/elftoolchain/libelf/gelf_phdr.c	Fri Dec 16 01:39:06 2016	(r310136)
+++ head/contrib/elftoolchain/libelf/gelf_phdr.c	Fri Dec 16 01:42:51 2016	(r310137)
@@ -53,10 +53,17 @@ gelf_getphdr(Elf *e, int index, GElf_Phd
 	Elf64_Ehdr *eh64;
 	Elf32_Phdr *ep32;
 	Elf64_Phdr *ep64;
+	size_t phnum;
 
 	if (d == NULL || e == NULL ||
 	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
-	    (e->e_kind != ELF_K_ELF) || index < 0) {
+	    (e->e_kind != ELF_K_ELF) || index < 0 ||
+	    elf_getphdrnum(e, &phnum) < 0) {
+		LIBELF_SET_ERROR(ARGUMENT, 0);
+		return (NULL);
+	}
+
+	if ((size_t)index >= phnum) {
 		LIBELF_SET_ERROR(ARGUMENT, 0);
 		return (NULL);
 	}
@@ -66,11 +73,6 @@ gelf_getphdr(Elf *e, int index, GElf_Phd
 		    ((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL))
 			return (NULL);
 
-		if (index >= eh32->e_phnum) {
-			LIBELF_SET_ERROR(ARGUMENT, 0);
-			return (NULL);
-		}
-
 		ep32 += index;
 
 		d->p_type   = ep32->p_type;
@@ -87,11 +89,6 @@ gelf_getphdr(Elf *e, int index, GElf_Phd
 		    (ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL)
 			return (NULL);
 
-		if (index >= eh64->e_phnum) {
-			LIBELF_SET_ERROR(ARGUMENT, 0);
-			return (NULL);
-		}
-
 		ep64 += index;
 
 		*d = *ep64;
@@ -125,13 +122,15 @@ gelf_newphdr(Elf *e, size_t count)
 int
 gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s)
 {
-	int ec, phnum;
+	int ec;
+	size_t phnum;
 	void *ehdr;
 	Elf32_Phdr *ph32;
 	Elf64_Phdr *ph64;
 
 	if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF ||
-	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
+	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
+	    elf_getphdrnum(e, &phnum) < 0) {
 		LIBELF_SET_ERROR(ARGUMENT, 0);
 		return (0);
 	}
@@ -144,12 +143,7 @@ gelf_update_phdr(Elf *e, int ndx, GElf_P
 	if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
 		return (0);
 
-	if (ec == ELFCLASS32)
-		phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
-	else
-		phnum = ((Elf64_Ehdr *) ehdr)->e_phnum;
-
-	if (ndx < 0 || ndx > phnum) {
+	if (ndx < 0 || (size_t)ndx > phnum) {
 		LIBELF_SET_ERROR(ARGUMENT, 0);
 		return (0);
 	}


More information about the svn-src-head mailing list