X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=fs%2Fexec.c;h=25dcbe5fc35664d6f389ce48f051d6528d607014;hb=6ea77d1384ed0c2d040a1934ecc3fd7187580931;hp=da80612a35f42e9bc1bb2d09fe79090e44b3808b;hpb=1a43f2012455a977397deffe35912fd3f3ce17b9;p=~andy%2Flinux diff --git a/fs/exec.c b/fs/exec.c index da80612a35f..25dcbe5fc35 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)