diff options
author | Suleiman Souhlal <ssouhlal@FreeBSD.org> | 2006-08-30 19:37:20 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-08-30 16:05:16 -0700 |
commit | ec0063b40a2291e095faf07fbeb94be92e525c54 (patch) | |
tree | c8605faccf1781687b91dafeaba6bdd6c2f10943 /arch/x86_64/ia32 | |
parent | 01ebb77b31149d847726a8847ad0d37631d7f049 (diff) | |
download | linux-ec0063b40a2291e095faf07fbeb94be92e525c54.tar.gz linux-ec0063b40a2291e095faf07fbeb94be92e525c54.tar.bz2 linux-ec0063b40a2291e095faf07fbeb94be92e525c54.zip |
[PATCH] x86_64: Don't write out segments from vsyscall32 DSO if it is not mapped
It's possible to get an invalid page fault in kernel mode when we try to
write out segments from vsyscall32 when dumping core for a 32bit process if
the vsyscall32 DSO is not mapped in its address space (which can happen if,
for example, ulimit -v 100 is run).
Signed-off-by: Suleiman Souhlal <suleiman@google.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/ia32')
-rw-r--r-- | arch/x86_64/ia32/ia32_binfmt.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index a9dc0f3b5b51..2fd5a67fd435 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c @@ -73,39 +73,44 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; * Dumping its extra ELF program headers includes all the other information * a debugger needs to easily find how the vsyscall DSO was being used. */ -#define ELF_CORE_EXTRA_PHDRS (VSYSCALL32_EHDR->e_phnum) +#define ELF_CORE_EXTRA_PHDRS (find_vma(current->mm, VSYSCALL32_BASE) ? \ + (VSYSCALL32_EHDR->e_phnum) : 0) #define ELF_CORE_WRITE_EXTRA_PHDRS \ do { \ - const struct elf32_phdr *const vsyscall_phdrs = \ - (const struct elf32_phdr *) (VSYSCALL32_BASE \ - + VSYSCALL32_EHDR->e_phoff); \ - int i; \ - Elf32_Off ofs = 0; \ - for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ - struct elf32_phdr phdr = vsyscall_phdrs[i]; \ - if (phdr.p_type == PT_LOAD) { \ - BUG_ON(ofs != 0); \ - ofs = phdr.p_offset = offset; \ - phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ - phdr.p_filesz = phdr.p_memsz; \ - offset += phdr.p_filesz; \ + if (find_vma(current->mm, VSYSCALL32_BASE)) { \ + const struct elf32_phdr *const vsyscall_phdrs = \ + (const struct elf32_phdr *) (VSYSCALL32_BASE \ + + VSYSCALL32_EHDR->e_phoff);\ + int i; \ + Elf32_Off ofs = 0; \ + for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ + struct elf32_phdr phdr = vsyscall_phdrs[i]; \ + if (phdr.p_type == PT_LOAD) { \ + BUG_ON(ofs != 0); \ + ofs = phdr.p_offset = offset; \ + phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ + phdr.p_filesz = phdr.p_memsz; \ + offset += phdr.p_filesz; \ + } \ + else \ + phdr.p_offset += ofs; \ + phdr.p_paddr = 0; /* match other core phdrs */ \ + DUMP_WRITE(&phdr, sizeof(phdr)); \ } \ - else \ - phdr.p_offset += ofs; \ - phdr.p_paddr = 0; /* match other core phdrs */ \ - DUMP_WRITE(&phdr, sizeof(phdr)); \ } \ } while (0) #define ELF_CORE_WRITE_EXTRA_DATA \ do { \ - const struct elf32_phdr *const vsyscall_phdrs = \ - (const struct elf32_phdr *) (VSYSCALL32_BASE \ - + VSYSCALL32_EHDR->e_phoff); \ - int i; \ - for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ - if (vsyscall_phdrs[i].p_type == PT_LOAD) \ - DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr, \ - PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ + if (find_vma(current->mm, VSYSCALL32_BASE)) { \ + const struct elf32_phdr *const vsyscall_phdrs = \ + (const struct elf32_phdr *) (VSYSCALL32_BASE \ + + VSYSCALL32_EHDR->e_phoff); \ + int i; \ + for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ + if (vsyscall_phdrs[i].p_type == PT_LOAD) \ + DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,\ + PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ + } \ } \ } while (0) |