diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 17 |
1 files changed, 17 insertions, 0 deletions
@@ -1459,6 +1459,23 @@ static int do_execve_common(const char *filename, | |||
1459 | struct files_struct *displaced; | 1459 | struct files_struct *displaced; |
1460 | bool clear_in_exec; | 1460 | bool clear_in_exec; |
1461 | int retval; | 1461 | int retval; |
1462 | const struct cred *cred = current_cred(); | ||
1463 | |||
1464 | /* | ||
1465 | * We move the actual failure in case of RLIMIT_NPROC excess from | ||
1466 | * set*uid() to execve() because too many poorly written programs | ||
1467 | * don't check setuid() return code. Here we additionally recheck | ||
1468 | * whether NPROC limit is still exceeded. | ||
1469 | */ | ||
1470 | if ((current->flags & PF_NPROC_EXCEEDED) && | ||
1471 | atomic_read(&cred->user->processes) > rlimit(RLIMIT_NPROC)) { | ||
1472 | retval = -EAGAIN; | ||
1473 | goto out_ret; | ||
1474 | } | ||
1475 | |||
1476 | /* We're below the limit (still or again), so we don't want to make | ||
1477 | * further execve() calls fail. */ | ||
1478 | current->flags &= ~PF_NPROC_EXCEEDED; | ||
1462 | 1479 | ||
1463 | retval = unshare_files(&displaced); | 1480 | retval = unshare_files(&displaced); |
1464 | if (retval) | 1481 | if (retval) |