ALSA: usb-audio: add support for Akai MPD16
[safe/jmp/linux-2.6] / fs / exec.c
index ea78617..e6e94c6 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -195,7 +195,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                 *    to work from.
                 */
                rlim = current->signal->rlim;
-               if (size > rlim[RLIMIT_STACK].rlim_cur / 4) {
+               if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
                        put_page(page);
                        return NULL;
                }
@@ -246,6 +246,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
        vma->vm_start = vma->vm_end - PAGE_SIZE;
        vma->vm_flags = VM_STACK_FLAGS;
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+       INIT_LIST_HEAD(&vma->anon_vma_chain);
        err = insert_vm_struct(mm, vma);
        if (err)
                goto err;
@@ -516,7 +517,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
        /*
         * cover the whole range: [new_start, old_end)
         */
-       vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL);
+       if (vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL))
+               return -ENOMEM;
 
        /*
         * move the page tables downwards, on failure we rely on
@@ -547,15 +549,13 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
        tlb_finish_mmu(tlb, new_end, old_end);
 
        /*
-        * shrink the vma to just the new range.
+        * Shrink the vma to just the new range.  Always succeeds.
         */
        vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL);
 
        return 0;
 }
 
-#define EXTRA_STACK_VM_PAGES   20      /* random */
-
 /*
  * Finalizes the stack vm_area_struct. The flags and permissions are updated,
  * the stack is optionally relocated, and some extra space is added.
@@ -577,7 +577,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
 
 #ifdef CONFIG_STACK_GROWSUP
        /* Limit stack size to 1GB */
-       stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max;
+       stack_base = rlimit_max(RLIMIT_STACK);
        if (stack_base > (1 << 30))
                stack_base = 1 << 30;
 
@@ -630,7 +630,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
                        goto out_unlock;
        }
 
-       stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+       stack_expand = 131072UL; /* randomly 32*4k (or 2*64k) pages */
        stack_size = vma->vm_end - vma->vm_start;
        /*
         * Align this down to a page boundary as expand_stack
@@ -1387,8 +1387,6 @@ int do_execve(char * filename,
        if (retval < 0)
                goto out;
 
-       current->stack_start = current->mm->start_stack;
-
        /* execve succeeded */
        current->fs->in_exec = 0;
        current->in_execve = 0;
@@ -1533,7 +1531,7 @@ static int format_corename(char *corename, long signr)
                        /* core limit size */
                        case 'c':
                                rc = snprintf(out_ptr, out_end - out_ptr,
-                                             "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur);
+                                             "%lu", rlimit(RLIMIT_CORE));
                                if (rc > out_end - out_ptr)
                                        goto out;
                                out_ptr += rc;
@@ -1561,12 +1559,13 @@ out:
        return ispipe;
 }
 
-static int zap_process(struct task_struct *start)
+static int zap_process(struct task_struct *start, int exit_code)
 {
        struct task_struct *t;
        int nr = 0;
 
        start->signal->flags = SIGNAL_GROUP_EXIT;
+       start->signal->group_exit_code = exit_code;
        start->signal->group_stop_count = 0;
 
        t = start;
@@ -1591,8 +1590,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
        spin_lock_irq(&tsk->sighand->siglock);
        if (!signal_group_exit(tsk->signal)) {
                mm->core_state = core_state;
-               tsk->signal->group_exit_code = exit_code;
-               nr = zap_process(tsk);
+               nr = zap_process(tsk, exit_code);
        }
        spin_unlock_irq(&tsk->sighand->siglock);
        if (unlikely(nr < 0))
@@ -1641,7 +1639,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
                        if (p->mm) {
                                if (unlikely(p->mm == mm)) {
                                        lock_task_sighand(p, &flags);
-                                       nr += zap_process(p);
+                                       nr += zap_process(p, exit_code);
                                        unlock_task_sighand(p, &flags);
                                }
                                break;
@@ -1748,14 +1746,19 @@ void set_dumpable(struct mm_struct *mm, int value)
        }
 }
 
-int get_dumpable(struct mm_struct *mm)
+static int __get_dumpable(unsigned long mm_flags)
 {
        int ret;
 
-       ret = mm->flags & 0x3;
+       ret = mm_flags & MMF_DUMPABLE_MASK;
        return (ret >= 2) ? 2 : ret;
 }
 
+int get_dumpable(struct mm_struct *mm)
+{
+       return __get_dumpable(mm->flags);
+}
+
 static void wait_for_dump_helpers(struct file *file)
 {
        struct pipe_inode_info *pipe;
@@ -1798,7 +1801,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
        struct coredump_params cprm = {
                .signr = signr,
                .regs = regs,
-               .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur,
+               .limit = rlimit(RLIMIT_CORE),
+               /*
+                * We must use the same mm->flags while dumping core to avoid
+                * inconsistency of bit flags, since this flag is not protected
+                * by any locks.
+                */
+               .mm_flags = mm->flags,
        };
 
        audit_core_dumps(signr);
@@ -1817,7 +1826,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
        /*
         * If another thread got here first, or we are not dumpable, bail out.
         */
-       if (mm->core_state || !get_dumpable(mm)) {
+       if (mm->core_state || !__get_dumpable(cprm.mm_flags)) {
                up_write(&mm->mmap_sem);
                put_cred(cred);
                goto fail;
@@ -1828,7 +1837,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
         *      process nor do we know its entire history. We only know it
         *      was tainted so we dump it as root in mode 2.
         */
-       if (get_dumpable(mm) == 2) {    /* Setuid core dump mode */
+       if (__get_dumpable(cprm.mm_flags) == 2) {
+               /* Setuid core dump mode */
                flag = O_EXCL;          /* Stop rewrite attacks */
                cred->fsuid = 0;        /* Dump root private */
        }
@@ -1924,8 +1934,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
        /*
         * Dont allow local users get cute and trick others to coredump
         * into their pre-created files:
+        * Note, this is not relevant for pipes
         */
-       if (inode->i_uid != current_fsuid())
+       if (!ispipe && (inode->i_uid != current_fsuid()))
                goto close_fail;
        if (!cprm.file->f_op)
                goto close_fail;