#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
#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)
{
#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 */
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.
}
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