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);
        }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to