]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/binfmt_elf.c
[PATCH] binfmt: fix uaccess handling
[linux-2.6-omap-h63xx.git] / fs / binfmt_elf.c
index 79b05a1a436582ebfd2415a682cce4a322be00d5..68e20d5bfe1b63b415f2e48c315c1636f45bb9ca 100644 (file)
@@ -243,8 +243,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
        if (interp_aout) {
                argv = sp + 2;
                envp = argv + argc + 1;
-               __put_user((elf_addr_t)(unsigned long)argv, sp++);
-               __put_user((elf_addr_t)(unsigned long)envp, sp++);
+               if (__put_user((elf_addr_t)(unsigned long)argv, sp++) ||
+                   __put_user((elf_addr_t)(unsigned long)envp, sp++))
+                       return -EFAULT;
        } else {
                argv = sp;
                envp = argv + argc + 1;
@@ -254,7 +255,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
        p = current->mm->arg_end = current->mm->arg_start;
        while (argc-- > 0) {
                size_t len;
-               __put_user((elf_addr_t)p, argv++);
+               if (__put_user((elf_addr_t)p, argv++))
+                       return -EFAULT;
                len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES);
                if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
                        return 0;
@@ -265,7 +267,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
        current->mm->arg_end = current->mm->env_start = p;
        while (envc-- > 0) {
                size_t len;
-               __put_user((elf_addr_t)p, envp++);
+               if (__put_user((elf_addr_t)p, envp++))
+                       return -EFAULT;
                len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES);
                if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
                        return 0;
@@ -856,7 +859,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                         * default mmap base, as well as whatever program they
                         * might try to exec.  This is because the brk will
                         * follow the loader, and is not movable.  */
-                       load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
+                       if (current->flags & PF_RANDOMIZE)
+                               load_bias = randomize_range(0x10000,
+                                                           ELF_ET_DYN_BASE,
+                                                           0);
+                       else
+                               load_bias = ELF_ET_DYN_BASE;
+                       load_bias = ELF_PAGESTART(load_bias - vaddr);
                }
 
                error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
@@ -1582,6 +1591,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
                
                sz += thread_status_size;
 
+#ifdef ELF_CORE_WRITE_EXTRA_NOTES
+               sz += ELF_CORE_EXTRA_NOTES_SIZE;
+#endif
+
                fill_elf_note_phdr(&phdr, sz, offset);
                offset += sz;
                DUMP_WRITE(&phdr, sizeof(phdr));
@@ -1622,6 +1635,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
                if (!writenote(notes + i, file, &foffset))
                        goto end_coredump;
 
+#ifdef ELF_CORE_WRITE_EXTRA_NOTES
+       ELF_CORE_WRITE_EXTRA_NOTES;
+#endif
+
        /* write out the thread status notes section */
        list_for_each(t, &thread_list) {
                struct elf_thread_status *tmp =