seccomp: allow mode setting across threads
[firefly-linux-kernel-4.4.55.git] / fs / exec.c
index 643019585574956f44bdca47c52c3993046db069..cb5fb9aa320ed558087a25138b43c8e26934478f 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1135,13 +1135,6 @@ void setup_new_exec(struct linux_binprm * bprm)
                        set_dumpable(current->mm, suid_dumpable);
        }
 
-       /*
-        * Flush performance counters when crossing a
-        * security domain:
-        */
-       if (!get_dumpable(current->mm))
-               perf_event_exit_task(current);
-
        /* An exec changes our domain. We are no longer part of the thread
           group */
 
@@ -1205,6 +1198,15 @@ void install_exec_creds(struct linux_binprm *bprm)
 
        commit_creds(bprm->cred);
        bprm->cred = NULL;
+
+       /*
+        * Disable monitoring for regular users
+        * when executing setuid binaries. Must
+        * wait until new credentials are committed
+        * by commit_creds() above
+        */
+       if (get_dumpable(current->mm) != SUID_DUMP_USER)
+               perf_event_exit_task(current);
        /*
         * cred_guard_mutex must be held at least to this point to prevent
         * ptrace_attach() from altering our determination of the task's
@@ -1237,7 +1239,7 @@ static int check_unsafe_exec(struct linux_binprm *bprm)
         * This isn't strictly necessary, but it makes it harder for LSMs to
         * mess up.
         */
-       if (current->no_new_privs)
+       if (task_no_new_privs(current))
                bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS;
 
        n_fs = 1;
@@ -1284,7 +1286,7 @@ int prepare_binprm(struct linux_binprm *bprm)
        bprm->cred->egid = current_egid();
 
        if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) &&
-           !current->no_new_privs &&
+           !task_no_new_privs(current) &&
            kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) &&
            kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) {
                /* Set-uid? */