]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Improve coredump_dir on FreeBSD and Solaris based OS (#974)
authorDavid CARLIER <devnexen@gmail.com>
Wed, 9 Feb 2022 19:38:21 +0000 (19:38 +0000)
committerSquid Anubis <squid-anubis@squid-cache.org>
Thu, 10 Feb 2022 20:23:05 +0000 (20:23 +0000)
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.

configure.ac
src/cf.data.pre
src/tools.cc

index f45b60018abcdf8f5797679484b60aa8136f020f..a4bcf4924d68f88864fea1355efa59173a681474 100644 (file)
@@ -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 \
index 17acbb425dbd843d3770f89c7722af8dc14f9ac3..7d78d9c1dde87fce69f0d3fe18333c53d4467608 100644 (file)
@@ -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
index 67d87140f87bb82bcaebc8de5eeb7775fb3be131..a6757b2511cc20ab2337728899deb6a14c5d1799 100644 (file)
 #if HAVE_SYS_PRCTL_H
 #include <sys/prctl.h>
 #endif
+#if HAVE_SYS_PROCCTL_H
+#include <sys/procctl.h>
+#endif
+#if HAVE_PRIV_H
+#include <priv.h>
+#endif
 #if HAVE_WIN32_PSAPI
 #include <psapi.h>
 #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