diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/check-textrel.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/elf/check-textrel.c b/elf/check-textrel.c index ec97e4b0c9..a39174dc3a 100644 --- a/elf/check-textrel.c +++ b/elf/check-textrel.c @@ -1,5 +1,5 @@ /* Check for text relocations in DSOs. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contribute by Ulrich Drepper <drepper@redhat.com>. 2002. @@ -79,20 +79,28 @@ AB(handle_file) (const char *fname, int fd) /* Search for the PT_DYNAMIC entry. */ size_t cnt; + E(Phdr) *dynphdr = NULL; for (cnt = 0; cnt < phnum; ++cnt) if (SWAP (phdr[cnt].p_type) == PT_DYNAMIC) - break; - - if (cnt == phnum) + dynphdr = &phdr[cnt]; + else if (SWAP (phdr[cnt].p_type) == PT_LOAD + && (SWAP (phdr[cnt].p_flags) & (PF_X | PF_W)) == (PF_X | PF_W)) + { + printf ("%s: segment %zu is executable and writable\n", + fname); + return 1; + } + + if (dynphdr == NULL) { printf ("%s: no DYNAMIC segment found\n", fname); return 1; } /* Read the dynamic segment. */ - size_t pmemsz = SWAP(phdr[cnt].p_memsz); + size_t pmemsz = SWAP(dynphdr->p_memsz); E(Dyn) *dyn = alloca (pmemsz); - if (pread (fd, dyn, pmemsz, SWAP(phdr[cnt].p_offset)) != pmemsz) + if (pread (fd, dyn, pmemsz, SWAP(dynphdr->p_offset)) != pmemsz) goto read_error; /* Search for an DT_TEXTREL entry of DT_FLAGS with the DF_TEXTREL |