Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm...
[pandora-kernel.git] / fs / exec.c
index e001bdf..52c9e2f 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1245,6 +1245,13 @@ static int check_unsafe_exec(struct linux_binprm *bprm)
                        bprm->unsafe |= LSM_UNSAFE_PTRACE;
        }
 
+       /*
+        * This isn't strictly necessary, but it makes it harder for LSMs to
+        * mess up.
+        */
+       if (current->no_new_privs)
+               bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS;
+
        n_fs = 1;
        spin_lock(&p->fs->lock);
        rcu_read_lock();
@@ -1288,7 +1295,8 @@ int prepare_binprm(struct linux_binprm *bprm)
        bprm->cred->euid = current_euid();
        bprm->cred->egid = current_egid();
 
-       if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
+       if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) &&
+           !current->no_new_privs) {
                /* Set-uid? */
                if (mode & S_ISUID) {
                        if (!kuid_has_mapping(bprm->cred->user_ns, inode->i_uid))
@@ -1376,7 +1384,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
        unsigned int depth = bprm->recursion_depth;
        int try,retval;
        struct linux_binfmt *fmt;
-       pid_t old_pid;
+       pid_t old_pid, old_vpid;
 
        retval = security_bprm_check(bprm);
        if (retval)
@@ -1387,8 +1395,9 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
                return retval;
 
        /* Need to fetch pid before load_binary changes it */
+       old_pid = current->pid;
        rcu_read_lock();
-       old_pid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
+       old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
        rcu_read_unlock();
 
        retval = -ENOENT;
@@ -1411,7 +1420,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
                        if (retval >= 0) {
                                if (depth == 0) {
                                        trace_sched_process_exec(current, old_pid, bprm);
-                                       ptrace_event(PTRACE_EVENT_EXEC, old_pid);
+                                       ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
                                }
                                put_binfmt(fmt);
                                allow_write_access(bprm->file);
@@ -1934,8 +1943,21 @@ static int coredump_wait(int exit_code, struct core_state *core_state)
                core_waiters = zap_threads(tsk, mm, core_state, exit_code);
        up_write(&mm->mmap_sem);
 
-       if (core_waiters > 0)
+       if (core_waiters > 0) {
+               struct core_thread *ptr;
+
                wait_for_completion(&core_state->startup);
+               /*
+                * Wait for all the threads to become inactive, so that
+                * all the thread context (extended register state, like
+                * fpu etc) gets copied to the memory.
+                */
+               ptr = core_state->dumper.next;
+               while (ptr != NULL) {
+                       wait_task_inactive(ptr->task, 0);
+                       ptr = ptr->next;
+               }
+       }
 
        return core_waiters;
 }