X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=fs%2Fexec.c;h=25dcbe5fc35664d6f389ce48f051d6528d607014;hb=d4001e086babc77f26b599893d803a2b6e46d602;hp=da80612a35f42e9bc1bb2d09fe79090e44b3808b;hpb=d7619fe39d9769b4d4545cc511c891deea18ae08;p=firefly-linux-kernel-4.4.55.git diff --git a/fs/exec.c b/fs/exec.c index da80612a35f4..25dcbe5fc356 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1459,6 +1459,23 @@ static int do_execve_common(const char *filename, struct files_struct *displaced; bool clear_in_exec; int retval; + const struct cred *cred = current_cred(); + + /* + * We move the actual failure in case of RLIMIT_NPROC excess from + * set*uid() to execve() because too many poorly written programs + * don't check setuid() return code. Here we additionally recheck + * whether NPROC limit is still exceeded. + */ + if ((current->flags & PF_NPROC_EXCEEDED) && + atomic_read(&cred->user->processes) > rlimit(RLIMIT_NPROC)) { + retval = -EAGAIN; + goto out_ret; + } + + /* We're below the limit (still or again), so we don't want to make + * further execve() calls fail. */ + current->flags &= ~PF_NPROC_EXCEEDED; retval = unshare_files(&displaced); if (retval)