Commit 8300ed7a authored by David Mosberger's avatar David Mosberger Committed by Linus Torvalds

[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
parent c2b2901b
...@@ -1025,6 +1025,23 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * 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 */ /* now stop all vm operations */
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
segs = current->mm->map_count; segs = current->mm->map_count;
...@@ -1068,7 +1085,6 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) ...@@ -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 * Set up the notes in similar form to SVR4 core dumps made
* with info from their /proc. * with info from their /proc.
*/ */
memset(&prstatus, 0, sizeof(prstatus));
notes[0].name = "CORE"; notes[0].name = "CORE";
notes[0].type = NT_PRSTATUS; notes[0].type = NT_PRSTATUS;
...@@ -1090,22 +1106,6 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) ...@@ -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_sec = CT_TO_SECS(current->times.tms_cstime);
prstatus.pr_cstime.tv_usec = CT_TO_USECS(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 #ifdef DEBUG
dump_regs("Passed in regs", (elf_greg_t *)regs); dump_regs("Passed in regs", (elf_greg_t *)regs);
dump_regs("prstatus regs", (elf_greg_t *)&prstatus.pr_reg); 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) ...@@ -1201,9 +1201,11 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
if (!maydump(vma)) if (!maydump(vma))
continue; continue;
#ifdef DEBUG #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 #endif
for (addr = vma->vm_start; for (addr = vma->vm_start;
addr < vma->vm_end; addr < vma->vm_end;
addr += PAGE_SIZE) { addr += PAGE_SIZE) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment