diff options
author | jkoshy <jkoshy@FreeBSD.org> | 2006-12-25 02:22:22 +0000 |
---|---|---|
committer | jkoshy <jkoshy@FreeBSD.org> | 2006-12-25 02:22:22 +0000 |
commit | 26d8253ac6532abcb8d1c8d57743998f5368173b (patch) | |
tree | 1f1c4db9c6b866adf56e5cc3eccd23baaa57af28 /lib/libelf/libelf_phdr.c | |
parent | 44313eba34c379a180dc73dcd02ab9c415941db3 (diff) | |
download | FreeBSD-src-26d8253ac6532abcb8d1c8d57743998f5368173b.zip FreeBSD-src-26d8253ac6532abcb8d1c8d57743998f5368173b.tar.gz |
Keep shadow copies of the `e_shnum', `e_phnum' and `e_shstrndx'
members of the ELF Executable Header inside the library-private
`struct _Elf' descriptor and only update the underlying Elf{32,64}_Ehdr
structure on an elf_update(3) call. These fields of the Ehdr
structure are technically `out of bounds' for an application program
per the ELF(3) API, but we've seen applications that initialize
a new Ehdr structure using memcpy(), messing up the library's
invariants. [1]
Implement elf_getphnum() and handle ELF objects with more than
64K program header table entries.
Reported by: jb [1]
Diffstat (limited to 'lib/libelf/libelf_phdr.c')
-rw-r--r-- | lib/libelf/libelf_phdr.c | 34 |
1 files changed, 13 insertions, 21 deletions
diff --git a/lib/libelf/libelf_phdr.c b/lib/libelf/libelf_phdr.c index 5ba58d4..fd43851 100644 --- a/lib/libelf/libelf_phdr.c +++ b/lib/libelf/libelf_phdr.c @@ -66,14 +66,14 @@ _libelf_getphdr(Elf *e, int ec) if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) return (NULL); + phnum = e->e_u.e_elf.e_nphdr; + if (ec == ELFCLASS32) { eh32 = (Elf32_Ehdr *) ehdr; - phnum = eh32->e_phnum; phentsize = eh32->e_phentsize; phoff = (uint64_t) eh32->e_phoff; } else { eh64 = (Elf64_Ehdr *) ehdr; - phnum = eh64->e_phnum; phentsize = eh64->e_phentsize; phoff = (uint64_t) eh64->e_phoff; } @@ -112,9 +112,7 @@ _libelf_getphdr(Elf *e, int ec) void * _libelf_newphdr(Elf *e, int ec, size_t count) { - void *ehdr, *nphdr, *ophdr; - Elf32_Ehdr *eh32; - Elf64_Ehdr *eh64; + void *ehdr, *newphdr, *oldphdr; size_t msz; if (e == NULL) { @@ -135,31 +133,25 @@ _libelf_newphdr(Elf *e, int ec, size_t count) assert(msz > 0); - nphdr = NULL; - if (count > 0 && (nphdr = calloc(count, msz)) == NULL) { + newphdr = NULL; + if (count > 0 && (newphdr = calloc(count, msz)) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } if (ec == ELFCLASS32) { - if ((ophdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL) - free(ophdr); - e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) nphdr; + if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL) + free(oldphdr); + e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) newphdr; } else { - if ((ophdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL) - free(ophdr); - e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) nphdr; + if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL) + free(oldphdr); + e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) newphdr; } - if (ec == ELFCLASS32) { - eh32 = (Elf32_Ehdr *) ehdr; - eh32->e_phnum = count; - } else { - eh64 = (Elf64_Ehdr *) ehdr; - eh64->e_phnum = count; - } + e->e_u.e_elf.e_nphdr = count; elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); - return (nphdr); + return (newphdr); } |