summaryrefslogtreecommitdiff
path: root/fs/binfmt_elf_fdpic.c
diff options
context:
space:
mode:
authorDaniel Schaeffer <daniel@dschaeffer.localdomain>2008-01-30 15:42:41 -0500
committerDaniel Schaeffer <daniel@dschaeffer.localdomain>2008-01-30 15:42:41 -0500
commit648b932d8cf61f38d08a84e6388036b22766c2df (patch)
tree3c48859a194482b645b93c1bead3bcc323327fb7 /fs/binfmt_elf_fdpic.c
parent2506ae0663e660d8dc7624fcdae1814c8ee3d10a (diff)
parentbbf25010f1a6b761914430f5fca081ec8c7accd1 (diff)
Merge branch '2.6.23' into 2.6.22.6-imx27
Conflicts: Documentation/kernel-parameters.txt Makefile arch/arm/Kconfig arch/arm/Makefile arch/arm/mach-mx3/Kconfig arch/arm/mach-mx3/Makefile arch/arm/mach-mx3/mm.c arch/arm/mach-mx3/mx31ads.c arch/arm/mm/Kconfig arch/arm/plat-mxc/Kconfig arch/arm/plat-mxc/Makefile arch/arm/plat-mxc/irq.c block/cfq-iosched.c drivers/ata/ahci.c drivers/ata/libata-core.c drivers/char/watchdog/Kconfig drivers/firewire/fw-sbp2.c drivers/md/dm-crypt.c drivers/media/video/pwc/pwc-if.c drivers/mmc/card/Kconfig drivers/mmc/card/queue.c drivers/mmc/core/Makefile drivers/mmc/core/bus.c drivers/mmc/core/core.c drivers/mmc/core/host.c drivers/mmc/core/mmc.c drivers/mmc/core/sd.c drivers/mmc/core/sd_ops.c drivers/mmc/host/at91_mci.c drivers/mmc/host/sdhci.c drivers/net/bonding/bond_main.c drivers/net/fec.c drivers/net/forcedeth.c drivers/net/r8169.c drivers/net/sky2.c drivers/rtc/Kconfig drivers/rtc/Makefile drivers/spi/Kconfig drivers/spi/Makefile drivers/usb/gadget/Makefile drivers/usb/gadget/gadget_chips.h drivers/usb/host/ehci.h drivers/video/logo/logo.c drivers/w1/slaves/Makefile fs/9p/conv.c fs/direct-io.c fs/exec.c fs/ocfs2/file.c fs/signalfd.c fs/sysfs/file.c include/asm-arm/arch-mxc/dma.h include/asm-arm/arch-mxc/entry-macro.S include/asm-arm/arch-mxc/hardware.h include/asm-arm/arch-mxc/io.h include/asm-arm/arch-mxc/irqs.h include/asm-arm/arch-mxc/memory.h include/asm-arm/arch-mxc/mx31.h include/asm-arm/arch-mxc/mxc.h include/asm-arm/arch-mxc/system.h include/asm-arm/arch-mxc/timex.h include/asm-arm/arch-mxc/uncompress.h include/asm-arm/arch-mxc/vmalloc.h include/linux/fsl_devices.h include/linux/ioprio.h kernel/lockdep_proc.c kernel/signal.c mm/hugetlb.c mm/readahead.c net/bluetooth/rfcomm/tty.c net/bridge/br_device.c net/core/dev.c net/ieee80211/softmac/ieee80211softmac_assoc.c net/ieee80211/softmac/ieee80211softmac_wx.c net/ipv4/netfilter/nf_conntrack_proto_icmp.c net/ipv4/tcp_input.c net/netfilter/nf_conntrack_proto_sctp.c
Diffstat (limited to 'fs/binfmt_elf_fdpic.c')
-rw-r--r--fs/binfmt_elf_fdpic.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 9d62fbad3d4b..2f5d8dbe676d 100644
--- 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++);
- 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;
}
@@ -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++);
- 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;
}
@@ -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.
*/
-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);
@@ -1197,27 +1199,35 @@ static int maydump(struct vm_area_struct *vma)
return 0;
}
- /* Dump shared memory only if mapped from an anonymous file. */
+ /* By default, dump shared memory if mapped from an anonymous file. */
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
- /* If it hasn't been written to, don't write it out */
+ /* By default, if it hasn't been written to, don't write it out */
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
- 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 */
@@ -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
-static int elf_fdpic_dump_segments(struct file *file, struct mm_struct *mm,
- size_t *size, unsigned long *limit)
+static int elf_fdpic_dump_segments(struct file *file, size_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;
- if (!maydump(vma))
+ if (!maydump(vma, mm_flags))
continue;
for (addr = vma->vm_start;
@@ -1511,15 +1521,15 @@ end_coredump:
* dump the segments for a NOMMU process
*/
#ifndef CONFIG_MMU
-static int elf_fdpic_dump_segments(struct file *file, struct mm_struct *mm,
- size_t *size, unsigned long *limit)
+static int elf_fdpic_dump_segments(struct file *file, size_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;
- if (!maydump(vma))
+ if (!maydump(vma, mm_flags))
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;
+ unsigned long mm_flags;
/*
* 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);
+ /*
+ * 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
@@ -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_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;
@@ -1762,7 +1780,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
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