]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] fix for elf coredump deadlock
authorDavid Mosberger <davidm@hpl.hp.com>
Mon, 11 Feb 2002 13:09:37 +0000 (05:09 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Mon, 11 Feb 2002 13:09:37 +0000 (05:09 -0800)
This patch fixes a deadlock condition in the elf core dump that shows
on ia64 because ELF_CORE_COPY_REGS() needs to access user space (to
get a hold of the backing store of the stacked registers).  Marcelo
already accepted this into 2.4.17.

--david

fs/binfmt_elf.c

index 2b8a35d2a940daff543d06de7d6c9a60cdcb0eac..3ca4e62e435698a352e0c42069d48117dbbf487a 100644 (file)
@@ -1025,6 +1025,23 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
 
        }
 
+       memset(&prstatus, 0, sizeof(prstatus));
+       /*
+        * This transfers the registers from regs into the standard
+        * coredump arrangement, whatever that is.
+        */
+#ifdef ELF_CORE_COPY_REGS
+       ELF_CORE_COPY_REGS(prstatus.pr_reg, regs)
+#else
+       if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
+       {
+               printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n",
+                       (long)sizeof(elf_gregset_t), (long)sizeof(struct pt_regs));
+       }
+       else
+               *(struct pt_regs *)&prstatus.pr_reg = *regs;
+#endif
+
        /* now stop all vm operations */
        down_write(&current->mm->mmap_sem);
        segs = current->mm->map_count;
@@ -1068,7 +1085,6 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
         * Set up the notes in similar form to SVR4 core dumps made
         * with info from their /proc.
         */
-       memset(&prstatus, 0, sizeof(prstatus));
 
        notes[0].name = "CORE";
        notes[0].type = NT_PRSTATUS;
@@ -1090,22 +1106,6 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
        prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
        prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime);
 
-       /*
-        * This transfers the registers from regs into the standard
-        * coredump arrangement, whatever that is.
-        */
-#ifdef ELF_CORE_COPY_REGS
-       ELF_CORE_COPY_REGS(prstatus.pr_reg, regs)
-#else
-       if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
-       {
-               printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n",
-                       (long)sizeof(elf_gregset_t), (long)sizeof(struct pt_regs));
-       }
-       else
-               *(struct pt_regs *)&prstatus.pr_reg = *regs;
-#endif
-
 #ifdef DEBUG
        dump_regs("Passed in regs", (elf_greg_t *)regs);
        dump_regs("prstatus regs", (elf_greg_t *)&prstatus.pr_reg);
@@ -1201,9 +1201,11 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
 
                if (!maydump(vma))
                        continue;
+
 #ifdef DEBUG
-               printk("elf_core_dump: writing %08lx %lx\n", addr, len);
+               printk("elf_core_dump: writing %08lx-%08lx\n", vma->vm_start, vma->vm_end);
 #endif
+
                for (addr = vma->vm_start;
                     addr < vma->vm_end;
                     addr += PAGE_SIZE) {