diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-06-30 17:01:07 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-06-30 17:01:07 +0000 |
commit | 2f6773b574652038ce4455fffbfc5931725dbc13 (patch) | |
tree | 3d3daee715d9937ec8f736f45bde1b0859c80946 | |
parent | 7d9d8bd18906fdd17364f372b160d7ab896ce909 (diff) | |
download | glibc-2f6773b574652038ce4455fffbfc5931725dbc13.tar.gz glibc-2f6773b574652038ce4455fffbfc5931725dbc13.tar.xz glibc-2f6773b574652038ce4455fffbfc5931725dbc13.zip |
(open_verify): Find .note.ABI-tag notes even in PT_NOTE segments with multiple notes.
-rw-r--r-- | elf/dl-load.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c index 025b9fd86b..73e9b9ce7b 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1634,7 +1634,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, { ElfW(Ehdr) *ehdr; ElfW(Phdr) *phdr, *ph; - ElfW(Word) *abi_note, abi_note_buf[8]; + ElfW(Word) *abi_note; unsigned int osversion; size_t maplength; @@ -1751,20 +1751,37 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, /* 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) + if (ph->p_type == PT_NOTE && ph->p_filesz >= 32 && ph->p_align >= 4) { - if (ph->p_offset + 32 <= (size_t) fbp->len) + ElfW(Addr) size = ph->p_filesz; + + if (ph->p_offset + size <= (size_t) fbp->len) abi_note = (void *) (fbp->buf + ph->p_offset); else { + abi_note = alloca (size); __lseek (fd, ph->p_offset, SEEK_SET); - if (__libc_read (fd, (void *) abi_note_buf, 32) != 32) + if (__libc_read (fd, (void *) abi_note, size) != size) goto read_error; + } + + while (memcmp (abi_note, &expected_note, sizeof (expected_note))) + { +#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word))) + ElfW(Addr) note_size = 3 * sizeof (ElfW(Word)) + + ROUND (abi_note[0]) + + ROUND (abi_note[1]); - abi_note = abi_note_buf; + if (size - 32 < note_size) + { + size = 0; + break; + } + size -= note_size; + abi_note = (void *) abi_note + note_size; } - if (memcmp (abi_note, &expected_note, sizeof (expected_note))) + if (size == 0) continue; osversion = (abi_note[5] & 0xff) * 65536 |