signal, x86: Delay calling signals in atomic on RT enabled kernels
[sfrench/cifs-2.6.git] / kernel / sys.c
index ecc4cf019242eb4202a684b07cd8437206e42119..97dc9e5d6bf92ca7e18c8f474d926e8c51d46679 100644 (file)
@@ -472,6 +472,16 @@ static int set_user(struct cred *new)
        if (!new_user)
                return -EAGAIN;
 
+       free_uid(new->user);
+       new->user = new_user;
+       return 0;
+}
+
+static void flag_nproc_exceeded(struct cred *new)
+{
+       if (new->ucounts == current_ucounts())
+               return;
+
        /*
         * We don't fail in case of NPROC limit excess here because too many
         * poorly written programs don't check set*uid() return code, assuming
@@ -480,15 +490,10 @@ static int set_user(struct cred *new)
         * failure to the execve() stage.
         */
        if (is_ucounts_overlimit(new->ucounts, UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC)) &&
-                       new_user != INIT_USER &&
-                       !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN))
+                       new->user != INIT_USER)
                current->flags |= PF_NPROC_EXCEEDED;
        else
                current->flags &= ~PF_NPROC_EXCEEDED;
-
-       free_uid(new->user);
-       new->user = new_user;
-       return 0;
 }
 
 /*
@@ -563,6 +568,7 @@ long __sys_setreuid(uid_t ruid, uid_t euid)
        if (retval < 0)
                goto error;
 
+       flag_nproc_exceeded(new);
        return commit_creds(new);
 
 error:
@@ -625,6 +631,7 @@ long __sys_setuid(uid_t uid)
        if (retval < 0)
                goto error;
 
+       flag_nproc_exceeded(new);
        return commit_creds(new);
 
 error:
@@ -704,6 +711,7 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
        if (retval < 0)
                goto error;
 
+       flag_nproc_exceeded(new);
        return commit_creds(new);
 
 error: