From: David Mosberger Date: Mon, 11 Feb 2002 13:09:37 +0000 (-0800) Subject: [PATCH] fix for elf coredump deadlock X-Git-Tag: v2.5.5-pre1~46 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=8300ed7ad3eecd2ae51db8c241453d395d274409;p=history.git [PATCH] fix for elf coredump deadlock 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 --- diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 2b8a35d2a940..3ca4e62e4356 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -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(¤t->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) {