vfs: Avoid softlockups with sendfile(2)
[linux-2.6-block.git] / fs / binfmt_elf.c
index 6b659967898ebc534c1ce8d91ff1179f050e8f34..3a93755e880fee23fa6d8370916caefb21f2c9eb 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/utsname.h>
 #include <linux/coredump.h>
 #include <linux/sched.h>
+#include <linux/dax.h>
 #include <asm/uaccess.h>
 #include <asm/param.h>
 #include <asm/page.h>
@@ -487,7 +488,7 @@ static inline int arch_elf_pt_proc(struct elfhdr *ehdr,
 }
 
 /**
- * arch_check_elf() - check a PT_LOPROC..PT_HIPROC ELF program header
+ * arch_check_elf() - check an ELF executable
  * @ehdr:      The main ELF header
  * @has_interp:        True if the ELF has an interpreter, else false.
  * @state:     Architecture-specific state preserved throughout the process
@@ -759,16 +760,16 @@ static int load_elf_binary(struct linux_binprm *bprm)
                         */
                        would_dump(bprm, interpreter);
 
-                       retval = kernel_read(interpreter, 0, bprm->buf,
-                                            BINPRM_BUF_SIZE);
-                       if (retval != BINPRM_BUF_SIZE) {
+                       /* Get the exec headers */
+                       retval = kernel_read(interpreter, 0,
+                                            (void *)&loc->interp_elf_ex,
+                                            sizeof(loc->interp_elf_ex));
+                       if (retval != sizeof(loc->interp_elf_ex)) {
                                if (retval >= 0)
                                        retval = -EIO;
                                goto out_free_dentry;
                        }
 
-                       /* Get the exec headers */
-                       loc->interp_elf_ex = *((struct elfhdr *)bprm->buf);
                        break;
                }
                elf_ppnt++;
@@ -1236,6 +1237,15 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
        if (vma->vm_flags & VM_DONTDUMP)
                return 0;
 
+       /* support for DAX */
+       if (vma_is_dax(vma)) {
+               if ((vma->vm_flags & VM_SHARED) && FILTER(DAX_SHARED))
+                       goto whole;
+               if (!(vma->vm_flags & VM_SHARED) && FILTER(DAX_PRIVATE))
+                       goto whole;
+               return 0;
+       }
+
        /* Hugetlb memory check */
        if (vma->vm_flags & VM_HUGETLB) {
                if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED))