aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-load.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-load.c')
-rw-r--r--elf/dl-load.c95
1 files changed, 15 insertions, 80 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 2fdd612997..2e4a010fc5 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1591,13 +1591,6 @@ open_verify (const char *name, int fd,
[EI_OSABI] = ELFOSABI_SYSV,
[EI_ABIVERSION] = 0
};
- static const struct
- {
- ElfW(Word) vendorlen;
- ElfW(Word) datalen;
- ElfW(Word) type;
- char vendor[4];
- } expected_note = { 4, 16, 1, "GNU" };
/* Initialize it to make the compiler happy. */
const char *errstring = NULL;
int errval = 0;
@@ -1628,10 +1621,7 @@ open_verify (const char *name, int fd,
if (fd != -1)
{
ElfW(Ehdr) *ehdr;
- ElfW(Phdr) *phdr, *ph;
- ElfW(Word) *abi_note;
- ElfW(Word) *abi_note_malloced = NULL;
- unsigned int osversion;
+ ElfW(Phdr) *phdr;
size_t maplength;
/* We successfully opened the file. Now verify it is a file
@@ -1695,13 +1685,16 @@ open_verify (const char *name, int fd,
#endif
)
errstring = N_("invalid ELF header");
+
else if (ehdr->e_ident[EI_CLASS] != ELFW(CLASS))
{
/* This is not a fatal error. On architectures where
32-bit and 64-bit binaries can be run this might
happen. */
*found_other_class = true;
- goto close_and_out;
+ __close_nocancel (fd);
+ __set_errno (ENOENT);
+ return -1;
}
else if (ehdr->e_ident[EI_DATA] != byteorder)
{
@@ -1736,7 +1729,11 @@ open_verify (const char *name, int fd,
goto lose;
}
if (! __glibc_likely (elf_machine_matches_host (ehdr)))
- goto close_and_out;
+ {
+ __close_nocancel (fd);
+ __set_errno (ENOENT);
+ return -1;
+ }
else if (__glibc_unlikely (ehdr->e_type != ET_DYN
&& ehdr->e_type != ET_EXEC))
{
@@ -1758,7 +1755,6 @@ open_verify (const char *name, int fd,
if ((size_t) __pread64_nocancel (fd, (void *) phdr, maplength,
ehdr->e_phoff) != maplength)
{
- read_error:
errval = errno;
errstring = N_("cannot read file data");
goto lose;
@@ -1768,73 +1764,12 @@ open_verify (const char *name, int fd,
if (__glibc_unlikely (elf_machine_reject_phdr_p
(phdr, ehdr->e_phnum, fbp->buf, fbp->len,
loader, fd)))
- goto close_and_out;
-
- /* Check .note.ABI-tag if present. */
- for (ph = phdr; ph < &phdr[ehdr->e_phnum]; ++ph)
- if (ph->p_type == PT_NOTE && ph->p_filesz >= 32
- && (ph->p_align == 4 || ph->p_align == 8))
- {
- ElfW(Addr) size = ph->p_filesz;
-
- if (ph->p_offset + size <= (size_t) fbp->len)
- abi_note = (void *) (fbp->buf + ph->p_offset);
- else
- {
- /* Note: __libc_use_alloca is not usable here, because
- thread info may not have been set up yet. */
- if (size < __MAX_ALLOCA_CUTOFF)
- abi_note = alloca (size);
- else
- {
- /* There could be multiple PT_NOTEs. */
- abi_note_malloced = realloc (abi_note_malloced, size);
- if (abi_note_malloced == NULL)
- goto read_error;
-
- abi_note = abi_note_malloced;
- }
- if (__pread64_nocancel (fd, (void *) abi_note, size,
- ph->p_offset) != size)
- {
- free (abi_note_malloced);
- goto read_error;
- }
- }
-
- while (memcmp (abi_note, &expected_note, sizeof (expected_note)))
- {
- ElfW(Addr) note_size
- = ELF_NOTE_NEXT_OFFSET (abi_note[0], abi_note[1],
- ph->p_align);
-
- if (size - 32 < note_size)
- {
- size = 0;
- break;
- }
- size -= note_size;
- abi_note = (void *) abi_note + note_size;
- }
-
- if (size == 0)
- continue;
-
- osversion = (abi_note[5] & 0xff) * 65536
- + (abi_note[6] & 0xff) * 256
- + (abi_note[7] & 0xff);
- if (abi_note[4] != __ABI_TAG_OS
- || (GLRO(dl_osversion) && GLRO(dl_osversion) < osversion))
- {
- close_and_out:
- __close_nocancel (fd);
- __set_errno (ENOENT);
- fd = -1;
- }
+ {
+ __close_nocancel (fd);
+ __set_errno (ENOENT);
+ return -1;
+ }
- break;
- }
- free (abi_note_malloced);
}
return fd;