disable_coredump: only change the soft limit, leave the hard limit as-is

This should avoid problems on Linux in cases where sudo does not
have CAP_SYS_RESOURCE which may be the case in an unprivileged container.
GitHub issue #42
This commit is contained in:
Todd C. Miller
2023-04-24 10:32:40 -06:00
parent e2243e3737
commit b1deffbe5b

View File

@@ -215,28 +215,40 @@ static int dumpflag;
void void
disable_coredump(void) disable_coredump(void)
{ {
struct rlimit rl = { 0, 0 };
debug_decl(disable_coredump, SUDO_DEBUG_UTIL); debug_decl(disable_coredump, SUDO_DEBUG_UTIL);
if (getrlimit(RLIMIT_CORE, &corelimit) == -1) if (getrlimit(RLIMIT_CORE, &corelimit) == 0) {
sudo_warn("getrlimit(RLIMIT_CORE)"); /*
sudo_debug_printf(SUDO_DEBUG_INFO, "RLIMIT_CORE [%lld, %lld] -> [0, 0]", * Set the soft limit to 0 but leave the existing hard limit.
(long long)corelimit.rlim_cur, (long long)corelimit.rlim_max); * On Linux, we need CAP_SYS_RESOURCE to raise the hard limit
if (setrlimit(RLIMIT_CORE, &rl) == -1) * which may not be the case in, e.g. an unprivileged container.
sudo_warn("setrlimit(RLIMIT_CORE)"); */
struct rlimit rl = corelimit;
rl.rlim_cur = 0;
sudo_debug_printf(SUDO_DEBUG_INFO,
"RLIMIT_CORE [%lld, %lld] -> [%lld, %lld]",
(long long)corelimit.rlim_cur, (long long)corelimit.rlim_max,
(long long)rl.rlim_cur, (long long)rl.rlim_max);
if (setrlimit(RLIMIT_CORE, &rl) == -1) {
sudo_warn("setrlimit(RLIMIT_CORE)");
} else {
coredump_disabled = true;
#ifdef __linux__ #ifdef __linux__
/* On Linux, also set PR_SET_DUMPABLE to zero (reset by execve). */ /* On Linux, also set PR_SET_DUMPABLE to zero (reset by execve). */
if ((dumpflag = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) == -1) { if ((dumpflag = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
"prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)"); "prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)");
dumpflag = 0; dumpflag = 0;
} }
if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1) { if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
"prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)"); "prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)");
} }
#endif /* __linux__ */ #endif /* __linux__ */
coredump_disabled = true; }
} else {
sudo_warn("getrlimit(RLIMIT_CORE)");
}
debug_return; debug_return;
} }
@@ -251,8 +263,8 @@ restore_coredump(void)
if (coredump_disabled) { if (coredump_disabled) {
/* /*
* Linux containers don't allow RLIMIT_CORE to be set back to * Do not warn about a failure to restore the core dump size limit.
* RLIM_INFINITY if we set the limit to zero, even for root. * This is mostly harmless and should not happen in practice.
*/ */
if (setrlimit(RLIMIT_CORE, &corelimit) == -1) { if (setrlimit(RLIMIT_CORE, &corelimit) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,