[PATCH] x86_64: Don't write out segments from vsyscall32 DSO if it is not mapped
authorSuleiman Souhlal <ssouhlal@FreeBSD.org>
Wed, 30 Aug 2006 17:37:20 +0000 (19:37 +0200)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 30 Aug 2006 23:05:16 +0000 (16:05 -0700)
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>
arch/x86_64/ia32/ia32_binfmt.c

index a9dc0f3b5b519dd711edb118393a2000c9ab7d6b..2fd5a67fd4353d4389a7b68ceab0c85186760c86 100644 (file)
@@ -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)