Merge branch 'x86-x32-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6.git] / fs / binfmt_elf.c
index 43ba478..48ffb3d 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/uaccess.h>
 #include <asm/param.h>
 #include <asm/page.h>
+#include <asm/exec.h>
 
 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
 static int load_elf_library(struct file *);
@@ -712,7 +713,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                goto out_free_dentry;
 
        /* OK, This is the point of no return */
-       current->flags &= ~PF_FORKNOEXEC;
        current->mm->def_flags = def_flags;
 
        /* Do this immediately, since STACK_TOP as used in setup_arg_pages
@@ -934,7 +934,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
 
        install_exec_creds(bprm);
-       current->flags &= ~PF_FORKNOEXEC;
        retval = create_elf_tables(bprm, &loc->elf_ex,
                          load_addr, interp_load_addr);
        if (retval < 0) {
@@ -1095,6 +1094,29 @@ out:
  */
 
 /*
+ * The purpose of always_dump_vma() is to make sure that special kernel mappings
+ * that are useful for post-mortem analysis are included in every core dump.
+ * In that way we ensure that the core dump is fully interpretable later
+ * without matching up the same kernel and hardware config to see what PC values
+ * meant. These special mappings include - vDSO, vsyscall, and other
+ * architecture specific mappings
+ */
+static bool always_dump_vma(struct vm_area_struct *vma)
+{
+       /* Any vsyscall mappings? */
+       if (vma == get_gate_vma(vma->vm_mm))
+               return true;
+       /*
+        * arch_vma_name() returns non-NULL for special architecture mappings,
+        * such as vDSO sections.
+        */
+       if (arch_vma_name(vma))
+               return true;
+
+       return false;
+}
+
+/*
  * Decide what to dump of a segment, part, all or none.
  */
 static unsigned long vma_dump_size(struct vm_area_struct *vma,
@@ -1102,10 +1124,13 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
 {
 #define FILTER(type)   (mm_flags & (1UL << MMF_DUMP_##type))
 
-       /* The vma can be set up to tell us the answer directly.  */
-       if (vma->vm_flags & VM_ALWAYSDUMP)
+       /* always dump the vdso and vsyscall sections */
+       if (always_dump_vma(vma))
                goto whole;
 
+       if (vma->vm_flags & VM_NODUMP)
+               return 0;
+
        /* Hugetlb memory check */
        if (vma->vm_flags & VM_HUGETLB) {
                if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED))
@@ -1437,7 +1462,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
        for (i = 1; i < view->n; ++i) {
                const struct user_regset *regset = &view->regsets[i];
                do_thread_regset_writeback(t->task, regset);
-               if (regset->core_note_type &&
+               if (regset->core_note_type && regset->get &&
                    (!regset->active || regset->active(t->task, regset))) {
                        int ret;
                        size_t size = regset->n * regset->size;
@@ -2093,7 +2118,8 @@ out:
 
 static int __init init_elf_binfmt(void)
 {
-       return register_binfmt(&elf_format);
+       register_binfmt(&elf_format);
+       return 0;
 }
 
 static void __exit exit_elf_binfmt(void)