git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Pull now into release branch
[pandora-kernel.git]
/
fs
/
binfmt_elf_fdpic.c
diff --git
a/fs/binfmt_elf_fdpic.c
b/fs/binfmt_elf_fdpic.c
index
9d62fba
..
2f5d8db
100644
(file)
--- a/
fs/binfmt_elf_fdpic.c
+++ b/
fs/binfmt_elf_fdpic.c
@@
-621,8
+621,8
@@
static int create_elf_fdpic_tables(struct linux_binprm *bprm,
p = (char __user *) current->mm->arg_start;
for (loop = bprm->argc; loop > 0; loop--) {
__put_user((elf_caddr_t) p, argv++);
p = (char __user *) current->mm->arg_start;
for (loop = bprm->argc; loop > 0; loop--) {
__put_user((elf_caddr_t) p, argv++);
- len = strnlen_user(p,
PAGE_SIZE * MAX_ARG_PAGES
);
- if (!len || len >
PAGE_SIZE * MAX_ARG_PAGES
)
+ len = strnlen_user(p,
MAX_ARG_STRLEN
);
+ if (!len || len >
MAX_ARG_STRLEN
)
return -EINVAL;
p += len;
}
return -EINVAL;
p += len;
}
@@
-633,8
+633,8
@@
static int create_elf_fdpic_tables(struct linux_binprm *bprm,
current->mm->env_start = (unsigned long) p;
for (loop = bprm->envc; loop > 0; loop--) {
__put_user((elf_caddr_t)(unsigned long) p, envp++);
current->mm->env_start = (unsigned long) p;
for (loop = bprm->envc; loop > 0; loop--) {
__put_user((elf_caddr_t)(unsigned long) p, envp++);
- len = strnlen_user(p,
PAGE_SIZE * MAX_ARG_PAGES
);
- if (!len || len >
PAGE_SIZE * MAX_ARG_PAGES
)
+ len = strnlen_user(p,
MAX_ARG_STRLEN
);
+ if (!len || len >
MAX_ARG_STRLEN
)
return -EINVAL;
p += len;
}
return -EINVAL;
p += len;
}
@@
-1181,8
+1181,10
@@
static int dump_seek(struct file *file, loff_t off)
*
* I think we should skip something. But I am not sure how. H.J.
*/
*
* I think we should skip something. But I am not sure how. H.J.
*/
-static int maydump(struct vm_area_struct *vma)
+static int maydump(struct vm_area_struct *vma
, unsigned long mm_flags
)
{
{
+ int dump_ok;
+
/* Do not dump I/O mapped devices or special mappings */
if (vma->vm_flags & (VM_IO | VM_RESERVED)) {
kdcore("%08lx: %08lx: no (IO)", vma->vm_start, vma->vm_flags);
/* Do not dump I/O mapped devices or special mappings */
if (vma->vm_flags & (VM_IO | VM_RESERVED)) {
kdcore("%08lx: %08lx: no (IO)", vma->vm_start, vma->vm_flags);
@@
-1197,27
+1199,35
@@
static int maydump(struct vm_area_struct *vma)
return 0;
}
return 0;
}
- /*
Dump shared memory onl
y if mapped from an anonymous file. */
+ /*
By default, dump shared memor
y if mapped from an anonymous file. */
if (vma->vm_flags & VM_SHARED) {
if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0) {
if (vma->vm_flags & VM_SHARED) {
if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0) {
- kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags);
- return 1;
+ dump_ok = test_bit(MMF_DUMP_ANON_SHARED, &mm_flags);
+ kdcore("%08lx: %08lx: %s (share)", vma->vm_start,
+ vma->vm_flags, dump_ok ? "yes" : "no");
+ return dump_ok;
}
}
- kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags);
- return 0;
+ dump_ok = test_bit(MMF_DUMP_MAPPED_SHARED, &mm_flags);
+ kdcore("%08lx: %08lx: %s (share)", vma->vm_start,
+ vma->vm_flags, dump_ok ? "yes" : "no");
+ return dump_ok;
}
#ifdef CONFIG_MMU
}
#ifdef CONFIG_MMU
- /*
I
f it hasn't been written to, don't write it out */
+ /*
By default, i
f it hasn't been written to, don't write it out */
if (!vma->anon_vma) {
if (!vma->anon_vma) {
- kdcore("%08lx: %08lx: no (!anon)", vma->vm_start, vma->vm_flags);
- return 0;
+ dump_ok = test_bit(MMF_DUMP_MAPPED_PRIVATE, &mm_flags);
+ kdcore("%08lx: %08lx: %s (!anon)", vma->vm_start,
+ vma->vm_flags, dump_ok ? "yes" : "no");
+ return dump_ok;
}
#endif
}
#endif
- kdcore("%08lx: %08lx: yes", vma->vm_start, vma->vm_flags);
- return 1;
+ dump_ok = test_bit(MMF_DUMP_ANON_PRIVATE, &mm_flags);
+ kdcore("%08lx: %08lx: %s", vma->vm_start, vma->vm_flags,
+ dump_ok ? "yes" : "no");
+ return dump_ok;
}
/* An ELF note in memory */
}
/* An ELF note in memory */
@@
-1456,15
+1466,15
@@
static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
* dump the segments for an MMU process
*/
#ifdef CONFIG_MMU
* dump the segments for an MMU process
*/
#ifdef CONFIG_MMU
-static int elf_fdpic_dump_segments(struct file *file, s
truct mm_struct *mm
,
-
size_t *size, unsigned long *limit
)
+static int elf_fdpic_dump_segments(struct file *file, s
ize_t *size
,
+
unsigned long *limit, unsigned long mm_flags
)
{
struct vm_area_struct *vma;
for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
unsigned long addr;
{
struct vm_area_struct *vma;
for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
unsigned long addr;
- if (!maydump(vma))
+ if (!maydump(vma
, mm_flags
))
continue;
for (addr = vma->vm_start;
continue;
for (addr = vma->vm_start;
@@
-1511,15
+1521,15
@@
end_coredump:
* dump the segments for a NOMMU process
*/
#ifndef CONFIG_MMU
* dump the segments for a NOMMU process
*/
#ifndef CONFIG_MMU
-static int elf_fdpic_dump_segments(struct file *file, s
truct mm_struct *mm
,
-
size_t *size, unsigned long *limit
)
+static int elf_fdpic_dump_segments(struct file *file, s
ize_t *size
,
+
unsigned long *limit, unsigned long mm_flags
)
{
struct vm_list_struct *vml;
for (vml = current->mm->context.vmlist; vml; vml = vml->next) {
struct vm_area_struct *vma = vml->vma;
{
struct vm_list_struct *vml;
for (vml = current->mm->context.vmlist; vml; vml = vml->next) {
struct vm_area_struct *vma = vml->vma;
- if (!maydump(vma))
+ if (!maydump(vma
, mm_flags
))
continue;
if ((*size += PAGE_SIZE) > *limit)
continue;
if ((*size += PAGE_SIZE) > *limit)
@@
-1570,6
+1580,7
@@
static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
struct vm_list_struct *vml;
#endif
elf_addr_t *auxv;
struct vm_list_struct *vml;
#endif
elf_addr_t *auxv;
+ unsigned long mm_flags;
/*
* We no longer stop all VM operations.
/*
* We no longer stop all VM operations.
@@
-1707,6
+1718,13
@@
static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
/* Page-align dumped data */
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
/* Page-align dumped data */
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
+ /*
+ * We must use the same mm->flags while dumping core to avoid
+ * inconsistency between the program headers and bodies, otherwise an
+ * unusable core file can be generated.
+ */
+ mm_flags = current->mm->flags;
+
/* write program headers for segments dump */
for (
#ifdef CONFIG_MMU
/* write program headers for segments dump */
for (
#ifdef CONFIG_MMU
@@
-1728,7
+1746,7
@@
static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
phdr.p_offset = offset;
phdr.p_vaddr = vma->vm_start;
phdr.p_paddr = 0;
phdr.p_offset = offset;
phdr.p_vaddr = vma->vm_start;
phdr.p_paddr = 0;
- phdr.p_filesz = maydump(vma) ? sz : 0;
+ phdr.p_filesz = maydump(vma
, mm_flags
) ? sz : 0;
phdr.p_memsz = sz;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
phdr.p_memsz = sz;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@
-1762,7
+1780,7
@@
static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
DUMP_SEEK(dataoff);
DUMP_SEEK(dataoff);
- if (elf_fdpic_dump_segments(file,
current->mm, &size, &limit
) < 0)
+ if (elf_fdpic_dump_segments(file,
&size, &limit, mm_flags
) < 0)
goto end_coredump;
#ifdef ELF_CORE_WRITE_EXTRA_DATA
goto end_coredump;
#ifdef ELF_CORE_WRITE_EXTRA_DATA