When restoring old resource limits, try to recover if we receive
EINVAL. On NetBSD, setrlimit(2) can return EINVAL if the new soft limit is lower than the current resource usage. This can be a problem when restoring the old stack limit if sudo has raised it.
This commit is contained in:
30
src/limits.c
30
src/limits.c
@@ -37,6 +37,7 @@
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
# include <sys/prctl.h>
|
# include <sys/prctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
@@ -236,7 +237,34 @@ restore_limits(void)
|
|||||||
for (idx = 0; idx < nitems(saved_limits); idx++) {
|
for (idx = 0; idx < nitems(saved_limits); idx++) {
|
||||||
struct saved_limit *lim = &saved_limits[idx];
|
struct saved_limit *lim = &saved_limits[idx];
|
||||||
if (lim->saved) {
|
if (lim->saved) {
|
||||||
if (setrlimit(lim->resource, &lim->oldlimit) == -1)
|
struct rlimit rl = lim->oldlimit;
|
||||||
|
int i, rc;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
rc = setrlimit(lim->resource, &rl);
|
||||||
|
if (rc != -1 || errno != EINVAL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Soft limit could be lower than current resource usage.
|
||||||
|
* This can be an issue on NetBSD with RLIMIT_STACK and ASLR.
|
||||||
|
*/
|
||||||
|
if (rl.rlim_cur > LLONG_MAX / 2)
|
||||||
|
break;
|
||||||
|
rl.rlim_cur *= 2;
|
||||||
|
if (lim->newlimit.rlim_cur != RLIM_INFINITY &&
|
||||||
|
rl.rlim_cur > lim->newlimit.rlim_cur) {
|
||||||
|
rl.rlim_cur = lim->newlimit.rlim_cur;
|
||||||
|
}
|
||||||
|
if (rl.rlim_max != RLIM_INFINITY &&
|
||||||
|
rl.rlim_cur > rl.rlim_max) {
|
||||||
|
rl.rlim_max = rl.rlim_cur;
|
||||||
|
}
|
||||||
|
rc = setrlimit(lim->resource, &rl);
|
||||||
|
if (rc != -1 || errno != EINVAL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rc == -1)
|
||||||
sudo_warn("setrlimit(%s)", lim->name);
|
sudo_warn("setrlimit(%s)", lim->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user