Don't set the RLIMIT_STACK soft/hard limits to unlimited.

Use 8Mb for soft and 64Mb for hard.
Works around issues on macOS and docker.  See also Bug #908
This commit is contained in:
Todd C. Miller
2019-11-11 17:57:10 -07:00
parent 4a893912ce
commit f3ebe5025a

View File

@@ -41,30 +41,33 @@
#include "sudo.h"
#ifndef OPEN_MAX
# define OPEN_MAX 256
#if defined(OPEN_MAX) && OPEN_MAX > 256
# define SUDO_OPEN_MAX OPEN_MAX
#else
# define SUDO_OPEN_MAX 256
#endif
static struct saved_limit {
int resource;
rlim_t fallback;
bool saved;
struct rlimit limit;
rlim_t fallback;
struct rlimit newlimit;
struct rlimit oldlimit;
} saved_limits[] = {
#ifdef RLIMIT_AS
{ RLIMIT_AS },
{ RLIMIT_AS, false, 0, { RLIM_INFINITY, RLIM_INFINITY } },
#endif
{ RLIMIT_CPU },
{ RLIMIT_DATA },
{ RLIMIT_FSIZE },
{ RLIMIT_NOFILE, OPEN_MAX },
{ RLIMIT_CPU, false, 0, { RLIM_INFINITY, RLIM_INFINITY } },
{ RLIMIT_DATA, false, 0, { RLIM_INFINITY, RLIM_INFINITY } },
{ RLIMIT_FSIZE, false, 0, { RLIM_INFINITY, RLIM_INFINITY } },
{ RLIMIT_NOFILE, false, SUDO_OPEN_MAX, { RLIM_INFINITY, RLIM_INFINITY } },
#ifdef RLIMIT_NPROC
{ RLIMIT_NPROC },
{ RLIMIT_NPROC, false, 0, { RLIM_INFINITY, RLIM_INFINITY } },
#endif
#ifdef RLIMIT_RSS
{ RLIMIT_RSS },
{ RLIMIT_RSS, false, 0, { RLIM_INFINITY, RLIM_INFINITY } },
#endif
{ RLIMIT_STACK }
{ RLIMIT_STACK, false, 0, { 8192 * 1024, 65532 * 1024 } }
};
static struct rlimit corelimit;
@@ -166,7 +169,6 @@ restore_nproc(void)
void
unlimit_sudo(void)
{
struct rlimit inf = { RLIM_INFINITY, RLIM_INFINITY };
unsigned int idx;
int rc;
debug_decl(unlimit_sudo, SUDO_DEBUG_UTIL)
@@ -174,24 +176,35 @@ unlimit_sudo(void)
/* Set resource limits to unlimited and stash the old values. */
for (idx = 0; idx < nitems(saved_limits); idx++) {
struct saved_limit *lim = &saved_limits[idx];
if (getrlimit(lim->resource, &lim->limit) == -1)
if (getrlimit(lim->resource, &lim->oldlimit) == -1)
continue;
lim->saved = true;
if (setrlimit(lim->resource, &inf) == -1) {
struct rlimit rl = lim->limit;
rl.rlim_cur = MAX(rl.rlim_max, lim->fallback);
if ((rc = setrlimit(lim->resource, &rl)) == -1) {
if (lim->fallback != 0) {
/* macOS won't set rlim_cur to RLIM_INFINITY for NOFILE */
rc = 0;
if (lim->fallback > lim->limit.rlim_cur) {
rl.rlim_cur = lim->fallback;
rc = setrlimit(lim->resource, &rl);
}
}
if (rc == -1)
sudo_warn("setrlimit(%d)", lim->resource);
if (lim->newlimit.rlim_cur != RLIM_INFINITY) {
/* Don't reduce the soft resource limit. */
if (lim->oldlimit.rlim_cur == RLIM_INFINITY ||
lim->oldlimit.rlim_cur > lim->newlimit.rlim_cur)
lim->newlimit.rlim_cur = lim->oldlimit.rlim_cur;
}
if (lim->newlimit.rlim_max != RLIM_INFINITY) {
/* Don't reduce the hard resource limit. */
if (lim->oldlimit.rlim_max == RLIM_INFINITY ||
lim->oldlimit.rlim_max > lim->newlimit.rlim_max)
lim->newlimit.rlim_max = lim->oldlimit.rlim_max;
}
if ((rc = setrlimit(lim->resource, &lim->newlimit)) == -1) {
if (lim->fallback != 0) {
/* macOS won't set rlim_cur to RLIM_INFINITY for NOFILE */
lim->newlimit.rlim_cur = lim->fallback;
rc = setrlimit(lim->resource, &lim->newlimit);
}
if (rc == -1) {
/* Try setting new rlim_cur to old rlim_max. */
lim->newlimit.rlim_cur = lim->oldlimit.rlim_max;
lim->newlimit.rlim_max = lim->oldlimit.rlim_max;
rc = setrlimit(lim->resource, &lim->newlimit);
}
if (rc == -1)
sudo_warn("setrlimit(%d)", lim->resource);
}
}
@@ -211,7 +224,7 @@ restore_limits(void)
for (idx = 0; idx < nitems(saved_limits); idx++) {
struct saved_limit *lim = &saved_limits[idx];
if (lim->saved) {
if (setrlimit(lim->resource, &lim->limit) == -1)
if (setrlimit(lim->resource, &lim->oldlimit) == -1)
sudo_warn("setrlimit(%d)", lim->resource);
}
}