Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 May 2017 01:57:06 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r317716 - stable/11/contrib/elftoolchain/libelf
Message-ID:  <201705030157.v431v6qs088483@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: emaste
Date: Wed May  3 01:57:06 2017
New Revision: 317716
URL: https://svnweb.freebsd.org/changeset/base/317716

Log:
  MFC libelf: Fix extended numbering
  
  r310136 (cem): libelf: Fix extended numbering detection
  
  Extended numbering is used for any of these fields overflowing.
  
  r310137 (cem): gelf_getphdr: Allow extended indices
  
  Needed for 'readelf -l' of extended phnum files.  (Parity with GNU
  binutils.)

Modified:
  stable/11/contrib/elftoolchain/libelf/gelf_phdr.c
  stable/11/contrib/elftoolchain/libelf/libelf_ehdr.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/contrib/elftoolchain/libelf/gelf_phdr.c
==============================================================================
--- stable/11/contrib/elftoolchain/libelf/gelf_phdr.c	Wed May  3 01:46:39 2017	(r317715)
+++ stable/11/contrib/elftoolchain/libelf/gelf_phdr.c	Wed May  3 01:57:06 2017	(r317716)
@@ -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);
 	}

Modified: stable/11/contrib/elftoolchain/libelf/libelf_ehdr.c
==============================================================================
--- stable/11/contrib/elftoolchain/libelf/libelf_ehdr.c	Wed May  3 01:46:39 2017	(r317715)
+++ stable/11/contrib/elftoolchain/libelf/libelf_ehdr.c	Wed May  3 01:57:06 2017	(r317716)
@@ -170,10 +170,6 @@ _libelf_ehdr(Elf *e, int ec, int allocat
 	(*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1,
 	    e->e_byteorder != LIBELF_PRIVATE(byteorder));
 
-	/*
-	 * If extended numbering is being used, read the correct
-	 * number of sections and program header entries.
-	 */
 	if (ec == ELFCLASS32) {
 		phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
 		shnum = ((Elf32_Ehdr *) ehdr)->e_shnum;
@@ -193,12 +189,19 @@ _libelf_ehdr(Elf *e, int ec, int allocat
 		return (NULL);
 	}
 
-	if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */
+	/*
+	 * If extended numbering is being used, read the correct
+	 * number of sections and program header entries.
+	 */
+	if ((shnum == 0 && shoff != 0) || phnum == PN_XNUM || strndx == SHN_XINDEX) {
+		if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0)
+			return (NULL);
+	} else {
+		/* not using extended numbering */
 		e->e_u.e_elf.e_nphdr = phnum;
 		e->e_u.e_elf.e_nscn = shnum;
 		e->e_u.e_elf.e_strndx = strndx;
-	} else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0)
-		return (NULL);
+	}
 
 	return (ehdr);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705030157.v431v6qs088483>