torerr.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /* Copyright (c) 2001, Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file torerr.c
  8. *
  9. * \brief Handling code for unrecoverable emergencies, at a lower level
  10. * than the logging code.
  11. *
  12. * There are plenty of places that things can go wrong in Tor's backend
  13. * libraries: the allocator can fail, the locking subsystem can fail, and so
  14. * on. But since these subsystems are used themselves by the logging module,
  15. * they can't use the logging code directly to report their errors.
  16. *
  17. * As a workaround, the logging code provides this module with a set of raw
  18. * fds to be used for reporting errors in the lowest-level Tor code.
  19. */
  20. #include "orconfig.h"
  21. #include <stdarg.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <stdio.h>
  25. #ifdef HAVE_SYS_TIME_H
  26. #include <sys/time.h>
  27. #endif
  28. #ifdef HAVE_TIME_H
  29. #include <time.h>
  30. #endif
  31. #ifdef HAVE_UNISTD_H
  32. #include <unistd.h>
  33. #endif
  34. #ifdef HAVE_SYS_TYPES_H
  35. #include <sys/types.h>
  36. #endif
  37. #include "lib/err/torerr.h"
  38. #include "lib/err/backtrace.h"
  39. /** Array of fds to log crash-style warnings to. */
  40. static int sigsafe_log_fds[TOR_SIGSAFE_LOG_MAX_FDS] = { STDERR_FILENO };
  41. /** The number of elements used in sigsafe_log_fds */
  42. static int n_sigsafe_log_fds = 1;
  43. /** Log granularity in milliseconds. */
  44. static int log_granularity = 1000;
  45. /** Write <b>s</b> to each element of sigsafe_log_fds. Return 0 on success, -1
  46. * on failure. */
  47. static int
  48. tor_log_err_sigsafe_write(const char *s)
  49. {
  50. int i;
  51. ssize_t r;
  52. size_t len = strlen(s);
  53. int err = 0;
  54. for (i=0; i < n_sigsafe_log_fds; ++i) {
  55. r = write(sigsafe_log_fds[i], s, len);
  56. err += (r != (ssize_t)len);
  57. }
  58. return err ? -1 : 0;
  59. }
  60. /** Given a list of string arguments ending with a NULL, writes them
  61. * to our logs and to stderr (if possible). This function is safe to call
  62. * from within a signal handler. */
  63. void
  64. tor_log_err_sigsafe(const char *m, ...)
  65. {
  66. va_list ap;
  67. const char *x;
  68. char timebuf[33];
  69. time_t now = time(NULL);
  70. if (!m)
  71. return;
  72. if (log_granularity >= 2000) {
  73. int g = log_granularity / 1000;
  74. now -= now % g;
  75. }
  76. timebuf[0] = now < 0 ? '-' : ' ';
  77. if (now < 0) now = -now;
  78. timebuf[1] = '\0';
  79. format_dec_number_sigsafe(now, timebuf+1, sizeof(timebuf)-1);
  80. tor_log_err_sigsafe_write("\n=========================================="
  81. "================== T=");
  82. tor_log_err_sigsafe_write(timebuf);
  83. tor_log_err_sigsafe_write("\n");
  84. tor_log_err_sigsafe_write(m);
  85. va_start(ap, m);
  86. while ((x = va_arg(ap, const char*))) {
  87. tor_log_err_sigsafe_write(x);
  88. }
  89. va_end(ap);
  90. }
  91. /** Set *<b>out</b> to a pointer to an array of the fds to log errors to from
  92. * inside a signal handler or other emergency condition. Return the number of
  93. * elements in the array. */
  94. int
  95. tor_log_get_sigsafe_err_fds(const int **out)
  96. {
  97. *out = sigsafe_log_fds;
  98. return n_sigsafe_log_fds;
  99. }
  100. /**
  101. * Update the list of fds that get errors from inside a signal handler or
  102. * other emergency condition. Ignore any beyond the first
  103. * TOR_SIGSAFE_LOG_MAX_FDS.
  104. *
  105. * These fds must remain open even after the log module has shut down. (And
  106. * they should remain open even while logs are being reconfigured.) Therefore,
  107. * any fds closed by the log module should be dup()ed, and the duplicate fd
  108. * should be given to the err module in fds. In particular, the log module
  109. * closes the file log fds, but does not close the stdio log fds.
  110. *
  111. * If fds is NULL or n is 0, clears the list of error fds.
  112. */
  113. void
  114. tor_log_set_sigsafe_err_fds(const int *fds, int n)
  115. {
  116. if (n > TOR_SIGSAFE_LOG_MAX_FDS) {
  117. n = TOR_SIGSAFE_LOG_MAX_FDS;
  118. }
  119. /* Clear the entire array. This code mitigates against some race conditions,
  120. * but there are still some races here:
  121. * - err logs are disabled while the array is cleared, and
  122. * - a thread can read the old value of n_sigsafe_log_fds, then read a
  123. * partially written array.
  124. * We could fix these races using atomics, but atomics use the err module. */
  125. n_sigsafe_log_fds = 0;
  126. memset(sigsafe_log_fds, 0, sizeof(sigsafe_log_fds));
  127. if (fds && n > 0) {
  128. memcpy(sigsafe_log_fds, fds, n * sizeof(int));
  129. n_sigsafe_log_fds = n;
  130. }
  131. }
  132. /**
  133. * Reset the list of emergency error fds to its default.
  134. */
  135. void
  136. tor_log_reset_sigsafe_err_fds(void)
  137. {
  138. int fds[] = { STDERR_FILENO };
  139. tor_log_set_sigsafe_err_fds(fds, 1);
  140. }
  141. /**
  142. * Close the list of fds that get errors from inside a signal handler or
  143. * other emergency condition. These fds are shared with the logging code:
  144. * closing them flushes the log buffers, and prevents any further logging.
  145. *
  146. * This function closes stderr, so it should only be called immediately before
  147. * process shutdown.
  148. */
  149. void
  150. tor_log_close_sigsafe_err_fds(void)
  151. {
  152. int n_fds, i;
  153. const int *fds = NULL;
  154. n_fds = tor_log_get_sigsafe_err_fds(&fds);
  155. for (i = 0; i < n_fds; ++i) {
  156. /* tor_log_close_sigsafe_err_fds_on_error() is called on error and on
  157. * shutdown, so we can't log or take any useful action if close()
  158. * fails. */
  159. (void)close(fds[i]);
  160. }
  161. /* Don't even try logging, we've closed all the log fds. */
  162. tor_log_set_sigsafe_err_fds(NULL, 0);
  163. }
  164. /**
  165. * Set the granularity (in ms) to use when reporting fatal errors outside
  166. * the logging system.
  167. */
  168. void
  169. tor_log_sigsafe_err_set_granularity(int ms)
  170. {
  171. log_granularity = ms;
  172. }
  173. /**
  174. * Log an emergency assertion failure message.
  175. *
  176. * This kind of message is safe to send from within a log handler,
  177. * a signal handler, or other emergency situation.
  178. */
  179. void
  180. tor_raw_assertion_failed_msg_(const char *file, int line, const char *expr,
  181. const char *msg)
  182. {
  183. char linebuf[16];
  184. format_dec_number_sigsafe(line, linebuf, sizeof(linebuf));
  185. tor_log_err_sigsafe("INTERNAL ERROR: Raw assertion failed in ",
  186. get_tor_backtrace_version(), " at ",
  187. file, ":", linebuf, ": ", expr, "\n", NULL);
  188. if (msg) {
  189. tor_log_err_sigsafe_write(msg);
  190. tor_log_err_sigsafe_write("\n");
  191. }
  192. dump_stack_symbols_to_error_fds();
  193. /* Some platforms (macOS, maybe others?) can swallow the last write before an
  194. * abort. This issue is probably caused by a race condition between write
  195. * buffer cache flushing, and process termination. So we write an extra
  196. * newline, to make sure that the message always gets through. */
  197. tor_log_err_sigsafe_write("\n");
  198. }
  199. /**
  200. * Call the abort() function to kill the current process with a fatal
  201. * error. But first, close the raw error file descriptors, so error messages
  202. * are written before process termination.
  203. **/
  204. void
  205. tor_raw_abort_(void)
  206. {
  207. tor_log_close_sigsafe_err_fds();
  208. abort();
  209. }
  210. /* As format_{hex,dex}_number_sigsafe, but takes a <b>radix</b> argument
  211. * in range 2..16 inclusive. */
  212. static int
  213. format_number_sigsafe(unsigned long x, char *buf, int buf_len,
  214. unsigned int radix)
  215. {
  216. unsigned long tmp;
  217. int len;
  218. char *cp;
  219. /* NOT tor_assert. This needs to be safe to run from within a signal
  220. * handler, and from within the 'tor_assert() has failed' code. Not even
  221. * raw_assert(), since raw_assert() calls this function on failure. */
  222. if (radix < 2 || radix > 16)
  223. return 0;
  224. /* Count how many digits we need. */
  225. tmp = x;
  226. len = 1;
  227. while (tmp >= radix) {
  228. tmp /= radix;
  229. ++len;
  230. }
  231. /* Not long enough */
  232. if (!buf || len >= buf_len)
  233. return 0;
  234. cp = buf + len;
  235. *cp = '\0';
  236. do {
  237. unsigned digit = (unsigned) (x % radix);
  238. if (cp <= buf) {
  239. /* Not tor_assert(); see above. */
  240. tor_raw_abort_();
  241. }
  242. --cp;
  243. *cp = "0123456789ABCDEF"[digit];
  244. x /= radix;
  245. } while (x);
  246. /* NOT tor_assert; see above. */
  247. if (cp != buf) {
  248. tor_raw_abort_(); // LCOV_EXCL_LINE
  249. }
  250. return len;
  251. }
  252. /**
  253. * Helper function to output hex numbers from within a signal handler.
  254. *
  255. * Writes the nul-terminated hexadecimal digits of <b>x</b> into a buffer
  256. * <b>buf</b> of size <b>buf_len</b>, and return the actual number of digits
  257. * written, not counting the terminal NUL.
  258. *
  259. * If there is insufficient space, write nothing and return 0.
  260. *
  261. * This accepts an unsigned int because format_helper_exit_status() needs to
  262. * call it with a signed int and an unsigned char, and since the C standard
  263. * does not guarantee that an int is wider than a char (an int must be at
  264. * least 16 bits but it is permitted for a char to be that wide as well), we
  265. * can't assume a signed int is sufficient to accommodate an unsigned char.
  266. * Thus, callers will still need to add any required '-' to the final string.
  267. *
  268. * For most purposes, you'd want to use tor_snprintf("%x") instead of this
  269. * function; it's designed to be used in code paths where you can't call
  270. * arbitrary C functions.
  271. */
  272. int
  273. format_hex_number_sigsafe(unsigned long x, char *buf, int buf_len)
  274. {
  275. return format_number_sigsafe(x, buf, buf_len, 16);
  276. }
  277. /** As format_hex_number_sigsafe, but format the number in base 10. */
  278. int
  279. format_dec_number_sigsafe(unsigned long x, char *buf, int buf_len)
  280. {
  281. return format_number_sigsafe(x, buf, buf_len, 10);
  282. }