From fb16cbc2643fb797589b96d55e4d3a35ce426b35 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 3 Oct 2003 00:17:11 -0700 Subject: [PATCH] [PATCH] fix vsyscall page in core dumps My change to core dumps that was included with the vsyscall DSO implementation had a bug (braino on my part). Core dumps don't include the full page of the vsyscall DSO, and so don't accurately represent the whole memory image of the process. This patch fixes it. I have tested it on x86, but not tested the same change to 32-bit core dumps on AMD64 (haven't even compiled on AMD64). I've also included the corresponding change for the IA64 code that was copied blindly from the x86 vsyscall implementation, which looks like more change than it is since I preserved the formatting of the copied code instead of arbitrarily diddling it along with the trivial symbol name changes. I haven't compiled or tested on ia64. --- arch/x86_64/ia32/ia32_binfmt.c | 9 +++++--- include/asm-i386/elf.h | 5 ++++- include/asm-ia64/elf.h | 38 +++++++++++++++++++--------------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index 7b102b1e89aef..7a4308c9c16b8 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c @@ -82,9 +82,12 @@ do { \ int i; \ Elf32_Off ofs = 0; \ for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ - struct elf_phdr phdr = vsyscall_phdrs[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 \ @@ -99,10 +102,10 @@ do { \ (const struct elf32_phdr *) (VSYSCALL32_BASE \ + VSYSCALL32_EHDR->e_phoff); \ int i; \ - for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ + for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \ if (vsyscall_phdrs[i].p_type == PT_LOAD) \ DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr, \ - vsyscall_phdrs[i].p_filesz); \ + PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ } \ } while (0) diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h index 2c2a91148d307..cda7f174b6947 100644 --- a/include/asm-i386/elf.h +++ b/include/asm-i386/elf.h @@ -157,7 +157,10 @@ do { \ for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \ struct elf_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 \ @@ -175,7 +178,7 @@ do { \ for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) { \ if (vsyscall_phdrs[i].p_type == PT_LOAD) \ DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \ - vsyscall_phdrs[i].p_filesz); \ + PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ } \ } while (0) diff --git a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h index b9930c5367ac5..cebb025766c24 100644 --- a/include/asm-ia64/elf.h +++ b/include/asm-ia64/elf.h @@ -206,42 +206,46 @@ do { \ NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \ } while (0) + /* - * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out extra segments - * containing the gate DSO contents. Dumping its contents makes post-mortem fully - * interpretable later without matching up the same kernel and hardware config to see what - * IP values meant. Dumping its extra ELF program headers includes all the other - * information a debugger needs to easily find how the gate DSO was being used. + * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out + * extra segments containing the gate DSO contents. Dumping its + * contents makes post-mortem fully interpretable later without matching up + * the same kernel and hardware config to see what PC values meant. + * Dumping its extra ELF program headers includes all the other information + * a debugger needs to easily find how the gate DSO was being used. */ #define ELF_CORE_EXTRA_PHDRS (GATE_EHDR->e_phnum) #define ELF_CORE_WRITE_EXTRA_PHDRS \ do { \ - const struct elf_phdr *const gate_phdrs = \ - (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \ + const struct elf_phdr *const vsyscall_phdrs = \ + (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \ int i; \ - Elf64_Off ofs = 0; \ + Elf32_Off ofs = 0; \ for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \ - struct elf_phdr phdr = gate_phdrs[i]; \ + struct elf_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 \ + } \ + 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 elf_phdr *const gate_phdrs = \ - (const struct elf_phdr *) (GATE_ADDR \ - + GATE_EHDR->e_phoff); \ + const struct elf_phdr *const vsyscall_phdrs = \ + (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \ int i; \ for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \ - if (gate_phdrs[i].p_type == PT_LOAD) \ - DUMP_WRITE((void *) gate_phdrs[i].p_vaddr, \ - gate_phdrs[i].p_filesz); \ + if (vsyscall_phdrs[i].p_type == PT_LOAD) \ + DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr, \ + PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ } \ } while (0) -- 2.53.0