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/elf_update.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/elf_update.c')
-rw-r--r-- | lib/libelf/elf_update.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/lib/libelf/elf_update.c b/lib/libelf/elf_update.c index c0203f9..5e8ee9c 100644 --- a/lib/libelf/elf_update.c +++ b/lib/libelf/elf_update.c @@ -346,7 +346,6 @@ _libelf_resync_elf(Elf *e) if (ec == ELFCLASS32) { eh_byteorder = eh32->e_ident[EI_DATA]; eh_class = eh32->e_ident[EI_CLASS]; - phnum = eh32->e_phnum; phoff = (uint64_t) eh32->e_phoff; shoff = (uint64_t) eh32->e_shoff; eh_type = eh32->e_type; @@ -354,7 +353,6 @@ _libelf_resync_elf(Elf *e) } else { eh_byteorder = eh64->e_ident[EI_DATA]; eh_class = eh64->e_ident[EI_CLASS]; - phnum = eh64->e_phnum; phoff = eh64->e_phoff; shoff = eh64->e_shoff; eh_type = eh64->e_type; @@ -379,8 +377,8 @@ _libelf_resync_elf(Elf *e) return ((off_t) -1); } - if (_libelf_getshnum(e, ehdr, ec, &shnum) == 0) - return ((off_t) -1); + shnum = e->e_u.e_elf.e_nscn; + phnum = e->e_u.e_elf.e_nphdr; e->e_byteorder = eh_byteorder; @@ -472,6 +470,13 @@ _libelf_resync_elf(Elf *e) shoff = 0; /* + * Set the fields of the Executable Header that could potentially use + * extended numbering. + */ + _libelf_setphnum(e, ehdr, ec, phnum); + _libelf_setshnum(e, ehdr, ec, shnum); + + /* * Update the `e_phoff' and `e_shoff' fields if the library is * doing the layout. */ @@ -638,18 +643,17 @@ _libelf_write_elf(Elf *e, off_t newsize) ehdr = _libelf_ehdr(e, ec, 0); assert(ehdr != NULL); + phnum = e->e_u.e_elf.e_nphdr; + if (ec == ELFCLASS32) { eh32 = (Elf32_Ehdr *) ehdr; - phnum = eh32->e_phnum; phoff = (uint64_t) eh32->e_phoff; shnum = eh32->e_shnum; shoff = (uint64_t) eh32->e_shoff; - } else { eh64 = (Elf64_Ehdr *) ehdr; - phnum = eh64->e_phnum; phoff = eh64->e_phoff; shnum = eh64->e_shnum; shoff = eh64->e_shoff; |