diff options
author | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-04-24 10:32:40 -0600 |
---|---|---|
committer | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-04-24 10:32:40 -0600 |
commit | fa927332aa8ecfd331edc4471310c9f2e48c874a (patch) | |
tree | 52a12c5ded443146b6789e38d56c603868cbb9d0 | |
parent | f9c47cbd45a57736b12af21f10315aa57b36174e (diff) | |
download | sudo-fa927332aa8ecfd331edc4471310c9f2e48c874a.tar.gz |
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
-rw-r--r-- | src/limits.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/src/limits.c b/src/limits.c index 32b770bb4..bda7e2961 100644 --- a/src/limits.c +++ b/src/limits.c @@ -215,28 +215,40 @@ static int dumpflag; void disable_coredump(void) { - struct rlimit rl = { 0, 0 }; debug_decl(disable_coredump, SUDO_DEBUG_UTIL); - if (getrlimit(RLIMIT_CORE, &corelimit) == -1) - sudo_warn("getrlimit(RLIMIT_CORE)"); - sudo_debug_printf(SUDO_DEBUG_INFO, "RLIMIT_CORE [%lld, %lld] -> [0, 0]", - (long long)corelimit.rlim_cur, (long long)corelimit.rlim_max); - if (setrlimit(RLIMIT_CORE, &rl) == -1) - sudo_warn("setrlimit(RLIMIT_CORE)"); + if (getrlimit(RLIMIT_CORE, &corelimit) == 0) { + /* + * Set the soft limit to 0 but leave the existing hard limit. + * On Linux, we need CAP_SYS_RESOURCE to raise the hard limit + * which may not be the case in, e.g. an unprivileged container. + */ + 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__ - /* On Linux, also set PR_SET_DUMPABLE to zero (reset by execve). */ - if ((dumpflag = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) == -1) { - sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, - "prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)"); - dumpflag = 0; - } - if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1) { - sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, - "prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)"); - } + /* On Linux, also set PR_SET_DUMPABLE to zero (reset by execve). */ + if ((dumpflag = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) == -1) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, + "prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)"); + dumpflag = 0; + } + if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, + "prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)"); + } #endif /* __linux__ */ - coredump_disabled = true; + } + } else { + sudo_warn("getrlimit(RLIMIT_CORE)"); + } debug_return; } @@ -251,8 +263,8 @@ restore_coredump(void) if (coredump_disabled) { /* - * Linux containers don't allow RLIMIT_CORE to be set back to - * RLIM_INFINITY if we set the limit to zero, even for root. + * Do not warn about a failure to restore the core dump size limit. + * This is mostly harmless and should not happen in practice. */ if (setrlimit(RLIMIT_CORE, &corelimit) == -1) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, |