]> git.hungrycats.org Git - linux/commitdiff
[PATCH] fix vsyscall page in core dumps
authorRoland McGrath <roland@redhat.com>
Fri, 3 Oct 2003 07:17:11 +0000 (00:17 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 3 Oct 2003 07:17:11 +0000 (00:17 -0700)
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
include/asm-i386/elf.h
include/asm-ia64/elf.h

index 7b102b1e89aef35101abc18802230449029610f7..7a4308c9c16b800abcf5e891af98b1026392a751 100644 (file)
@@ -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)
 
index 2c2a91148d307acbd96ee036d17096567f292378..cda7f174b69476b15583756397a30906784fdaeb 100644 (file)
@@ -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)
 
index b9930c5367ac5e5c6bb26f93588ea06072b219dc..cebb025766c247ddad266730b967ac8113eebbfa 100644 (file)
@@ -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)