37 #include <sys/prctl.h>
39 #if HAVE_SYS_PROCCTL_H
40 #include <sys/procctl.h>
59 The Squid Cache (version %s) died.\n\
61 You've encountered a fatal error in the Squid Cache version %s.\n\
62 If a core file was created (possibly in the swap directory),\n\
63 please execute 'gdb squid core' or 'dbx squid core', then type 'where',\n\
64 and report the trace back to squid-bugs@lists.squid-cache.org.\n\
76 SQUIDCEXTERN void backtrace_symbols_fd(
void *,
int,
int);
115 static char command[256];
124 const mode_t prev_umask=umask(S_IXUSR|S_IXGRP|S_IWGRP|S_IWOTH|S_IXOTH);
127 char filename[] =
"/tmp/squid-XXXXXX";
128 int tfd = mkstemp(filename);
129 if (tfd < 0 || (fp = fdopen(tfd,
"w")) ==
NULL) {
138 (fp = fopen(filename,
"w")) ==
NULL) {
151 fprintf(fp,
"Subject: %s\n",
dead_msg());
155 if (system(command)) {}
165 #if HAVE_MSTATS && HAVE_GNUMALLOC_H
167 struct mstats ms = mstats();
168 fprintf(
debug_log,
"\ttotal space in arena: %6d KB\n",
169 (
int) (ms.bytes_total >> 10));
170 fprintf(
debug_log,
"\tTotal free: %6d KB %d%%\n",
171 (
int) (ms.bytes_free >> 10),
179 memset(r,
'\0',
sizeof(
struct rusage));
180 #if HAVE_GETRUSAGE && defined(RUSAGE_SELF) && !_SQUID_WINDOWS_
186 getrusage(RUSAGE_SELF, r);
192 #elif _SQUID_WINDOWS_ && HAVE_WIN32_PSAPI
194 if (WIN32_OS_version >= _WIN_OS_WINNT) {
198 PROCESS_MEMORY_COUNTERS pmc;
199 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
201 FALSE, GetCurrentProcessId());
205 FILETIME ftCreate, ftExit, ftKernel, ftUser;
206 if (GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
207 int64_t *ptUser = (int64_t *)&ftUser;
208 int64_t tUser64 = *ptUser / 10;
209 int64_t *ptKernel = (int64_t *)&ftKernel;
210 int64_t tKernel64 = *ptKernel / 10;
211 r->
ru_utime.tv_sec =(long)(tUser64 / 1000000);
212 r->
ru_stime.tv_sec =(long)(tKernel64 / 1000000);
213 r->
ru_utime.tv_usec =(long)(tUser64 % 1000000);
214 r->
ru_stime.tv_usec =(long)(tKernel64 % 1000000);
216 CloseHandle( hProcess );
220 if (GetProcessMemoryInfo( hProcess, &pmc,
sizeof(pmc))) {
221 r->
ru_maxrss=(DWORD)(pmc.WorkingSetSize / getpagesize());
224 CloseHandle( hProcess );
228 CloseHandle( hProcess );
237 return (
double) r->
ru_stime.tv_sec +
239 (
double) r->
ru_stime.tv_usec / 1000000.0 +
244 #ifndef HAVE_GETPAGESIZE
245 #define HAVE_GETPAGESIZE 0
252 #if _SQUID_SGI_ && _ABIAPI
254 #elif _SQUID_SGI_|| _SQUID_OSF_ || _SQUID_AIX_ || defined(BSD4_4)
257 #elif defined(HAVE_GETPAGESIZE) && HAVE_GETPAGESIZE != 0
259 return (r->
ru_maxrss * getpagesize()) >> 10;
260 #elif defined(PAGESIZE)
273 #if _SQUID_SGI_ && _ABIAPI
287 const auto handleError = [](
const char *
const syscall,
const int savedErrno) {
290 #if HAVE_PRCTL && defined(PR_SET_DUMPABLE)
291 if (prctl(PR_SET_DUMPABLE, 1) != 0)
292 handleError(
"prctl(PR_SET_DUMPABLE)", errno);
293 #elif HAVE_PROCCTL && defined(PROC_TRACE_CTL)
296 int traceable = PROC_TRACE_CTL_ENABLE;
297 if (procctl(P_PID, getpid(), PROC_TRACE_CTL, &traceable) != 0)
298 handleError(
"procctl(PROC_TRACE_CTL_ENABLE)", errno);
300 if (setpflags(__PROC_PROTECT, 0) != 0)
301 handleError(
"setpflags(__PROC_PROTECT)", errno);
303 debugs(50, 2,
"WARNING: Assuming this process is traceable");
331 fprintf(
debug_log,
"CPU Usage: %.3f seconds = %.3f user + %.3f sys\n",
335 fprintf(
debug_log,
"Maximum Resident Size: %d KB\n",
337 fprintf(
debug_log,
"Page faults with physical i/o: %d\n",
346 else if (sig == SIGBUS)
351 #if PRINT_STACK_TRACE
354 extern void U_STACK_TRACE(
void);
361 #if _SQUID_SOLARIS_ && HAVE_LIBOPCOM_STACK
363 extern void opcom_stack_trace(
void);
371 #if HAVE_BACKTRACE_SYMBOLS_FD
373 static void *callarray[8192];
375 n = backtrace(callarray, 8192);
376 backtrace_symbols_fd(callarray, n, fileno(
debug_log));
382 #if SA_RESETHAND == 0 && !_SQUID_WINDOWS_
383 signal(SIGSEGV, SIG_DFL);
385 signal(SIGBUS, SIG_DFL);
387 signal(sig, SIG_DFL);
422 kill(kid.getPid(), sig);
432 static int state = 0;
467 static int present = 0;
493 debugs(50, 4,
"getMyHostname: resolved " << sa <<
" to '" << host <<
"'");
499 if (strchr(host,
'.'))
504 debugs(50, 2,
"WARNING: failed to resolve " << sa <<
" to a fully qualified hostname");
514 memset(&hints, 0,
sizeof(
addrinfo));
520 debugs(50, 6,
"getMyHostname: '" << host <<
"' has DNS resolution.");
537 debugs(50,
DBG_CRITICAL,
"WARNING: Could not determine this machines public hostname. " <<
538 "Please configure one or set 'visible_hostname'.");
540 return (
"localhost");
558 debugs(21, 3,
"leave_suid: PID " << getpid() <<
" called");
596 const auto xerrno = errno;
602 const auto xerrno = errno;
608 const auto xerrno = errno;
622 debugs(21, 3,
"enter_suid: PID " << getpid() <<
" taking root privileges");
624 if (setresuid((uid_t)-1, 0, (uid_t)-1) < 0) {
625 const auto xerrno = errno;
626 debugs (21, 3,
"enter_suid: setresuid failed: " <<
xstrerr(xerrno));
631 const auto xerrno = errno;
648 debugs(21, 3,
"no_suid: PID " << getpid() <<
" giving up root privileges forever");
655 if (setuid(uid) < 0) {
742 roles.
append(
" coordinator");
751 #ifndef RLIMIT_NOFILE
753 #define RLIMIT_NOFILE RLIMIT_OFILE
761 #if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE)
766 #if defined(getrlimit)
772 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
776 #if USE_SELECT || USE_SELECT_WIN32
779 rl.rlim_cur = FD_SETSIZE;
784 if (rl.rlim_cur > rl.rlim_max)
785 rl.rlim_max = rl.rlim_cur;
786 if (setrlimit(RLIMIT_NOFILE, &rl)) {
789 getrlimit(RLIMIT_NOFILE, &rl);
790 rl.rlim_cur = rl.rlim_max;
791 if (setrlimit(RLIMIT_NOFILE, &rl)) {
797 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
810 #if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) && !_SQUID_CYGWIN_
816 #if defined(getrlimit)
822 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
827 if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
835 #if HAVE_SETRLIMIT && defined(RLIMIT_DATA) && !_SQUID_CYGWIN_
836 if (getrlimit(RLIMIT_DATA, &rl) < 0) {
839 }
else if (rl.rlim_max > rl.rlim_cur) {
840 rl.rlim_cur = rl.rlim_max;
842 if (setrlimit(RLIMIT_DATA, &rl) < 0) {
853 #if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) && !_SQUID_CYGWIN_
854 if (getrlimit(RLIMIT_VMEM, &rl) < 0) {
857 }
else if (rl.rlim_max > rl.rlim_cur) {
858 rl.rlim_cur = rl.rlim_max;
860 if (setrlimit(RLIMIT_VMEM, &rl) < 0) {
875 sa.sa_handler = func;
877 sigemptyset(&sa.sa_mask);
879 if (sigaction(sig, &sa,
NULL) < 0) {
907 WIN32_ExceptionHandlerInit();
911 WIN32_ExceptionHandlerInit();
937 assert(label && obj && pm);
941 debugs(section, level,
"" << label <<
"" << mb.
buf <<
"");
968 setmode(fileno(fp),
O_TEXT);
971 while (fgets(buf, 1024, fp)) {
982 debugs(1, 5,
"etc_hosts: line is '" << buf <<
"'");
991 debugs(1, 5,
"etc_hosts: address is '" << addr <<
"'");
997 while ((nt = strpbrk(lt,
w_space))) {
1001 debugs(1, 5,
"etc_hosts: multiple spaces, skipping");
1007 debugs(1, 5,
"etc_hosts: got hostname '" << lt <<
"'");
1012 strncpy(buf2, lt,
sizeof(buf2)-1);
1014 buf2[
sizeof(buf2)-1] =
'\0';
1025 hosts.emplace_back(
SBuf(host));
1043 while (p !=
NULL && p->flags.isIntercepted())
1051 while (p !=
NULL && p->flags.isIntercepted())
1069 static const mode_t orig_umask = umask(mask);
1070 umask(mask | orig_umask);
1081 if (strchr(str,
' ')) {
1087 int l = strcspn(str,
"\"\\\n\r");
1121 #if USE_LIBCAP && HAVE_PRCTL && defined(PR_SET_KEEPCAPS)
1123 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
1136 caps = cap_get_proc();
1144 cap_value_t cap_list[10];
1145 cap_list[ncaps] = CAP_NET_BIND_SERVICE;
1148 #
if USE_LIBNETFILTERCONNTRACK
1155 cap_list[ncaps] = CAP_NET_ADMIN;
1159 cap_clear_flag(caps, CAP_EFFECTIVE);
1160 rc |= cap_set_flag(caps, CAP_EFFECTIVE, ncaps, cap_list, CAP_SET);
1161 rc |= cap_set_flag(caps, CAP_PERMITTED, ncaps, cap_list, CAP_SET);
1163 if (rc || cap_set_proc(caps) != 0) {
1182 return waitpid(
pid, &status, flags);
1188 WindowsErrorMessage(DWORD errorId)
1190 char *rawMessage =
nullptr;
1191 const auto length = FormatMessage(
1192 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1193 FORMAT_MESSAGE_FROM_SYSTEM |
1194 FORMAT_MESSAGE_IGNORE_INSERTS,
1197 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1198 static_cast<LPTSTR
>(&rawMessage),
1203 return ToSBuf(
"windows error ", errorId);
1205 const auto result =
SBuf(rawMessage, length);
1206 LocalFree(rawMessage);
1209 #endif // _SQUID_WINDOWS_