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>