From: David CARLIER Date: Wed, 9 Feb 2022 19:38:21 +0000 (+0000) Subject: Improve coredump_dir on FreeBSD and Solaris based OS (#974) X-Git-Tag: SQUID_6_0_1~237 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=321223fe636d87bbe4f61a9872d5685bf59dac4d;p=thirdparty%2Fsquid.git Improve coredump_dir on FreeBSD and Solaris based OS (#974) Disclose that coredump_dir may also make the process "traceable", including enabling core dumps and ptrace(2) attachments in certain environments. Add support for making the process traceable in FreeBSD- and Solaris-like environments. When Squid does not know how to make the process traceable in a given environment, it does nothing under the assumption that the process is already traceable enough (by default) to dump cores. Alternatively, we could warn the admin about the lack of tracing support for that environment. It is not clear which option is better, but we are betting on the processes being traceable by default in most not explicitly covered environments. --- diff --git a/configure.ac b/configure.ac index f45b60018a..a4bcf4924d 100644 --- a/configure.ac +++ b/configure.ac @@ -2701,6 +2701,7 @@ AC_CHECK_HEADERS( \ netinet/tcp.h \ paths.h \ poll.h \ + priv.h \ pwd.h \ regex.h \ sched.h \ @@ -2718,6 +2719,7 @@ AC_CHECK_HEADERS( \ sys/ipc.cc \ sys/param.h \ sys/prctl.h \ + sys/procctl.h \ sys/md5.h \ sys/mman.h \ sys/msg.h \ @@ -3187,6 +3189,7 @@ AC_CHECK_FUNCS(\ mstats \ poll \ prctl \ + procctl \ pthread_attr_setschedparam \ pthread_attr_setscope \ pthread_setschedparam \ @@ -3203,6 +3206,7 @@ AC_CHECK_FUNCS(\ select \ seteuid \ setgroups \ + setpflags \ setpgrp \ setsid \ sigaction \ diff --git a/src/cf.data.pre b/src/cf.data.pre index 17acbb425d..7d78d9c1dd 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -5639,6 +5639,11 @@ DOC_START that exists, Squid will chdir() to that directory at startup and coredump files will be left there. + In addition to changing the directory, the process permissions are updated + to enable process tracing and/or coredump file generation. The details are + OS-specific, but look for prctl(2) PR_SET_DUMPABLE and procctl(2) + PROC_TRACE_CTL documentation as guiding examples. + CONFIG_START # Leave coredumps in the first cache dir diff --git a/src/tools.cc b/src/tools.cc index 67d87140f8..a6757b2511 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -37,6 +37,12 @@ #if HAVE_SYS_PRCTL_H #include #endif +#if HAVE_SYS_PROCCTL_H +#include +#endif +#if HAVE_PRIV_H +#include +#endif #if HAVE_WIN32_PSAPI #include #endif @@ -273,6 +279,50 @@ rusage_pagefaults(struct rusage *r) #endif } +/// Make the process traceable if possible. Call setTraceability() instead! +/// Traceable processes may support attachment via ptrace(2) or ktrace(2), +/// debugging sysctls, hwpmc(4), dtrace(1) and core dumping. +static void +makeTraceable() +{ + const auto handleError = [](const char * const syscall, const int savedErrno) { + throw TextException(ToSBuf(syscall, " failure: ", xstrerr(savedErrno)), Here()); + }; +#if HAVE_PRCTL && defined(PR_SET_DUMPABLE) + if (prctl(PR_SET_DUMPABLE, 1) != 0) + handleError("prctl(PR_SET_DUMPABLE)", errno); +#elif HAVE_PROCCTL && defined(PROC_TRACE_CTL) + // TODO: when FreeBSD 14 becomes the lowest version, we can + // possibly save one getpid syscall, for now still necessary. + int traceable = PROC_TRACE_CTL_ENABLE; + if (procctl(P_PID, getpid(), PROC_TRACE_CTL, &traceable) != 0) + handleError("procctl(PROC_TRACE_CTL_ENABLE)", errno); +#elif HAVE_SETPFLAGS + if (setpflags(__PROC_PROTECT, 0) != 0) + handleError("setpflags(__PROC_PROTECT)", errno); +#else + debugs(50, 2, "WARNING: Assuming this process is traceable"); + (void)handleError; // just "use" the variable; there is no error here +#endif +} + +/// Make the process traceable if necessary. +/// \sa makeTraceable() +static void +setTraceability() +{ + // for now, setting coredump_dir is required to make the process traceable + if (!Config.coredump_dir) + return; + + try { + makeTraceable(); + } catch (...) { + debugs(50, DBG_IMPORTANT, "ERROR: Cannot make the process traceable:" << + Debug::Extra << "exception: " << CurrentException); + } +} + void PrintRusage(void) { @@ -563,14 +613,7 @@ leave_suid(void) #endif restoreCapabilities(true); - -#if HAVE_PRCTL && defined(PR_SET_DUMPABLE) - /* Set Linux DUMPABLE flag */ - if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0) { - int xerrno = errno; - debugs(50, 2, "ALERT: prctl: " << xstrerr(xerrno)); - } -#endif + setTraceability(); } /* Enter a privilegied section */ @@ -590,14 +633,8 @@ enter_suid(void) debugs(21, 3, "setuid(0) failed: " << xstrerr(xerrno)); } #endif -#if HAVE_PRCTL && defined(PR_SET_DUMPABLE) - /* Set Linux DUMPABLE flag */ - if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0) { - int xerrno = errno; - debugs(50, 2, "ALERT: prctl: " << xstrerr(xerrno)); - } -#endif + setTraceability(); } /* Give up the possibility to gain privilegies. @@ -622,14 +659,7 @@ no_suid(void) } restoreCapabilities(false); - -#if HAVE_PRCTL && defined(PR_SET_DUMPABLE) - /* Set Linux DUMPABLE flag */ - if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0) { - int xerrno = errno; - debugs(50, 2, "ALERT: prctl: " << xstrerr(xerrno)); - } -#endif + setTraceability(); } bool