| Kernel v2.4.17-rc2 /fs/binfmt_elf.c |
|---|
 2.4.17-rc2
 fs
 binfmt_elf.c
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.16/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- linux-2.4.16/fs/binfmt_elf.c Sun Oct 21 02:16:59 2001
+++ linux/fs/binfmt_elf.c Thu Dec 6 19:57:21 2001
@@ -32,7 +32,7 @@
#include <linux/highuid.h>
#include <linux/smp_lock.h>
#include <linux/compiler.h>
-#include <linux/limits.h>
+#include <linux/highmem.h>
#include <asm/uaccess.h>
#include <asm/param.h>
@@ -1032,6 +1032,25 @@
elf_fpregset_t fpu; /* NT_PRFPREG */
struct elf_prpsinfo psinfo; /* NT_PRPSINFO */
+ /* first copy the parameters from user space */
+ memset(&psinfo, 0, sizeof(psinfo));
+ {
+ int i, len;
+
+ len = current->mm->arg_end - current->mm->arg_start;
+ if (len >= ELF_PRARGSZ)
+ len = ELF_PRARGSZ-1;
+ copy_from_user(&psinfo.pr_psargs,
+ (const char *)current->mm->arg_start, len);
+ for(i = 0; i < len; i++)
+ if (psinfo.pr_psargs[i] == 0)
+ psinfo.pr_psargs[i] = ' ';
+ psinfo.pr_psargs[len] = 0;
+
+ }
+
+ /* now stop all vm operations */
+ down_write(¤t->mm->mmap_sem);
segs = current->mm->map_count;
#ifdef DEBUG
@@ -1073,7 +1092,6 @@
* Set up the notes in similar form to SVR4 core dumps made
* with info from their /proc.
*/
- memset(&psinfo, 0, sizeof(psinfo));
memset(&prstatus, 0, sizeof(prstatus));
notes[0].name = "CORE";
@@ -1129,23 +1147,6 @@
psinfo.pr_flag = current->flags;
psinfo.pr_uid = NEW_TO_OLD_UID(current->uid);
psinfo.pr_gid = NEW_TO_OLD_GID(current->gid);
- {
- int i, len;
-
- set_fs(fs);
-
- len = current->mm->arg_end - current->mm->arg_start;
- if (len >= ELF_PRARGSZ)
- len = ELF_PRARGSZ-1;
- copy_from_user(&psinfo.pr_psargs,
- (const char *)current->mm->arg_start, len);
- for(i = 0; i < len; i++)
- if (psinfo.pr_psargs[i] == 0)
- psinfo.pr_psargs[i] = ' ';
- psinfo.pr_psargs[len] = 0;
-
- set_fs(KERNEL_DS);
- }
strncpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
notes[2].name = "CORE";
@@ -1217,8 +1218,6 @@
if (!writenote(¬es[i], file))
goto end_coredump;
- set_fs(fs);
-
DUMP_SEEK(dataoff);
for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
@@ -1232,22 +1231,24 @@
for (addr = vma->vm_start;
addr < vma->vm_end;
addr += PAGE_SIZE) {
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte;
-
- pgd = pgd_offset(vma->vm_mm, addr);
- if (pgd_none(*pgd))
- goto nextpage_coredump;
- pmd = pmd_offset(pgd, addr);
- if (pmd_none(*pmd))
- goto nextpage_coredump;
- pte = pte_offset(pmd, addr);
- if (pte_none(*pte)) {
-nextpage_coredump:
+ struct page* page;
+ struct vm_area_struct *vma;
+
+ if (get_user_pages(current, current->mm, addr, 1, 0, 1,
+ &page, &vma) <= 0) {
DUMP_SEEK (file->f_pos + PAGE_SIZE);
} else {
- DUMP_WRITE((void*)addr, PAGE_SIZE);
+ if (page == ZERO_PAGE(addr)) {
+ DUMP_SEEK (file->f_pos + PAGE_SIZE);
+ } else {
+ void *kaddr;
+ flush_cache_page(vma, addr);
+ kaddr = kmap(page);
+ DUMP_WRITE(kaddr, PAGE_SIZE);
+ flush_page_to_ram(page);
+ kunmap(page);
+ }
+ put_page(page);
}
}
}
@@ -1260,6 +1261,7 @@
end_coredump:
set_fs(fs);
+ up_write(¤t->mm->mmap_sem);
return has_dumped;
}
#endif /* USE_ELF_CORE_DUMP */
|