util.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* Copyright (c) 2003, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file util.c
  7. * \brief Common functions for strings, IO, network, data structures,
  8. * process control.
  9. **/
  10. #include "orconfig.h"
  11. #ifdef HAVE_FCNTL_H
  12. #include <fcntl.h>
  13. #endif
  14. #define UTIL_PRIVATE
  15. #include "common/util.h"
  16. #include "lib/log/torlog.h"
  17. #include "lib/crypt_ops/crypto_digest.h"
  18. #include "lib/cc/torint.h"
  19. #include "lib/container/smartlist.h"
  20. #include "lib/fdio/fdio.h"
  21. #include "lib/net/address.h"
  22. #include "lib/sandbox/sandbox.h"
  23. #include "lib/err/backtrace.h"
  24. #include "lib/process/waitpid.h"
  25. #include "lib/encoding/binascii.h"
  26. #ifdef _WIN32
  27. #include <io.h>
  28. #include <direct.h>
  29. #include <process.h>
  30. #include <tchar.h>
  31. #include <winbase.h>
  32. #else /* !(defined(_WIN32)) */
  33. #include <dirent.h>
  34. #include <pwd.h>
  35. #include <grp.h>
  36. #endif /* defined(_WIN32) */
  37. /* math.h needs this on Linux */
  38. #ifndef _USE_ISOC99_
  39. #define _USE_ISOC99_ 1
  40. #endif
  41. #include <math.h>
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include <signal.h>
  46. #ifdef HAVE_NETINET_IN_H
  47. #include <netinet/in.h>
  48. #endif
  49. #ifdef HAVE_ARPA_INET_H
  50. #include <arpa/inet.h>
  51. #endif
  52. #ifdef HAVE_ERRNO_H
  53. #include <errno.h>
  54. #endif
  55. #ifdef HAVE_SYS_SOCKET_H
  56. #include <sys/socket.h>
  57. #endif
  58. #ifdef HAVE_SYS_TIME_H
  59. #include <sys/time.h>
  60. #endif
  61. #ifdef HAVE_UNISTD_H
  62. #include <unistd.h>
  63. #endif
  64. #ifdef HAVE_SYS_STAT_H
  65. #include <sys/stat.h>
  66. #endif
  67. #ifdef HAVE_SYS_FCNTL_H
  68. #include <sys/fcntl.h>
  69. #endif
  70. #ifdef HAVE_TIME_H
  71. #include <time.h>
  72. #endif
  73. #ifdef HAVE_MALLOC_MALLOC_H
  74. #include <malloc/malloc.h>
  75. #endif
  76. #ifdef HAVE_MALLOC_H
  77. #if !defined(OpenBSD) && !defined(__FreeBSD__)
  78. /* OpenBSD has a malloc.h, but for our purposes, it only exists in order to
  79. * scold us for being so stupid as to autodetect its presence. To be fair,
  80. * they've done this since 1996, when autoconf was only 5 years old. */
  81. #include <malloc.h>
  82. #endif /* !defined(OpenBSD) && !defined(__FreeBSD__) */
  83. #endif /* defined(HAVE_MALLOC_H) */
  84. #ifdef HAVE_MALLOC_NP_H
  85. #include <malloc_np.h>
  86. #endif
  87. #ifdef HAVE_SYS_WAIT_H
  88. #include <sys/wait.h>
  89. #endif
  90. #if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
  91. #include <sys/prctl.h>
  92. #endif
  93. /* =====
  94. * Memory management
  95. * ===== */
  96. DISABLE_GCC_WARNING(aggregate-return)
  97. /** Call the platform malloc info function, and dump the results to the log at
  98. * level <b>severity</b>. If no such function exists, do nothing. */
  99. void
  100. tor_log_mallinfo(int severity)
  101. {
  102. #ifdef HAVE_MALLINFO
  103. struct mallinfo mi;
  104. memset(&mi, 0, sizeof(mi));
  105. mi = mallinfo();
  106. tor_log(severity, LD_MM,
  107. "mallinfo() said: arena=%d, ordblks=%d, smblks=%d, hblks=%d, "
  108. "hblkhd=%d, usmblks=%d, fsmblks=%d, uordblks=%d, fordblks=%d, "
  109. "keepcost=%d",
  110. mi.arena, mi.ordblks, mi.smblks, mi.hblks,
  111. mi.hblkhd, mi.usmblks, mi.fsmblks, mi.uordblks, mi.fordblks,
  112. mi.keepcost);
  113. #else /* !(defined(HAVE_MALLINFO)) */
  114. (void)severity;
  115. #endif /* defined(HAVE_MALLINFO) */
  116. }
  117. ENABLE_GCC_WARNING(aggregate-return)
  118. /* =====
  119. * Math
  120. * ===== */
  121. /* =====
  122. * String manipulation
  123. * ===== */
  124. /* =====
  125. * Time
  126. * ===== */
  127. #define TOR_USEC_PER_SEC 1000000
  128. /** Return the difference between start->tv_sec and end->tv_sec.
  129. * Returns INT64_MAX on overflow and underflow.
  130. */
  131. static int64_t
  132. tv_secdiff_impl(const struct timeval *start, const struct timeval *end)
  133. {
  134. const int64_t s = (int64_t)start->tv_sec;
  135. const int64_t e = (int64_t)end->tv_sec;
  136. /* This may not be the most efficient way of implemeting this check,
  137. * but it's easy to see that it's correct and doesn't overflow */
  138. if (s > 0 && e < INT64_MIN + s) {
  139. /* s is positive: equivalent to e - s < INT64_MIN, but without any
  140. * overflow */
  141. return INT64_MAX;
  142. } else if (s < 0 && e > INT64_MAX + s) {
  143. /* s is negative: equivalent to e - s > INT64_MAX, but without any
  144. * overflow */
  145. return INT64_MAX;
  146. }
  147. return e - s;
  148. }
  149. /** Return the number of microseconds elapsed between *start and *end.
  150. * Returns LONG_MAX on overflow and underflow.
  151. */
  152. long
  153. tv_udiff(const struct timeval *start, const struct timeval *end)
  154. {
  155. /* Sanity check tv_usec */
  156. if (start->tv_usec > TOR_USEC_PER_SEC || start->tv_usec < 0) {
  157. log_warn(LD_GENERAL, "comparing times on microsecond detail with bad "
  158. "start tv_usec: " I64_FORMAT " microseconds",
  159. I64_PRINTF_ARG(start->tv_usec));
  160. return LONG_MAX;
  161. }
  162. if (end->tv_usec > TOR_USEC_PER_SEC || end->tv_usec < 0) {
  163. log_warn(LD_GENERAL, "comparing times on microsecond detail with bad "
  164. "end tv_usec: " I64_FORMAT " microseconds",
  165. I64_PRINTF_ARG(end->tv_usec));
  166. return LONG_MAX;
  167. }
  168. /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
  169. */
  170. int64_t udiff;
  171. const int64_t secdiff = tv_secdiff_impl(start, end);
  172. /* end->tv_usec - start->tv_usec can be up to 1 second either way */
  173. if (secdiff > (int64_t)(LONG_MAX/1000000 - 1) ||
  174. secdiff < (int64_t)(LONG_MIN/1000000 + 1)) {
  175. log_warn(LD_GENERAL, "comparing times on microsecond detail too far "
  176. "apart: " I64_FORMAT " seconds", I64_PRINTF_ARG(secdiff));
  177. return LONG_MAX;
  178. }
  179. /* we'll never get an overflow here, because we check that both usecs are
  180. * between 0 and TV_USEC_PER_SEC. */
  181. udiff = secdiff*1000000 + ((int64_t)end->tv_usec - (int64_t)start->tv_usec);
  182. /* Some compilers are smart enough to work out this is a no-op on L64 */
  183. #if SIZEOF_LONG < 8
  184. if (udiff > (int64_t)LONG_MAX || udiff < (int64_t)LONG_MIN) {
  185. return LONG_MAX;
  186. }
  187. #endif
  188. return (long)udiff;
  189. }
  190. /** Return the number of milliseconds elapsed between *start and *end.
  191. * If the tv_usec difference is 500, rounds away from zero.
  192. * Returns LONG_MAX on overflow and underflow.
  193. */
  194. long
  195. tv_mdiff(const struct timeval *start, const struct timeval *end)
  196. {
  197. /* Sanity check tv_usec */
  198. if (start->tv_usec > TOR_USEC_PER_SEC || start->tv_usec < 0) {
  199. log_warn(LD_GENERAL, "comparing times on millisecond detail with bad "
  200. "start tv_usec: " I64_FORMAT " microseconds",
  201. I64_PRINTF_ARG(start->tv_usec));
  202. return LONG_MAX;
  203. }
  204. if (end->tv_usec > TOR_USEC_PER_SEC || end->tv_usec < 0) {
  205. log_warn(LD_GENERAL, "comparing times on millisecond detail with bad "
  206. "end tv_usec: " I64_FORMAT " microseconds",
  207. I64_PRINTF_ARG(end->tv_usec));
  208. return LONG_MAX;
  209. }
  210. /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
  211. */
  212. int64_t mdiff;
  213. const int64_t secdiff = tv_secdiff_impl(start, end);
  214. /* end->tv_usec - start->tv_usec can be up to 1 second either way, but the
  215. * mdiff calculation may add another temporary second for rounding.
  216. * Whether this actually causes overflow depends on the compiler's constant
  217. * folding and order of operations. */
  218. if (secdiff > (int64_t)(LONG_MAX/1000 - 2) ||
  219. secdiff < (int64_t)(LONG_MIN/1000 + 1)) {
  220. log_warn(LD_GENERAL, "comparing times on millisecond detail too far "
  221. "apart: " I64_FORMAT " seconds", I64_PRINTF_ARG(secdiff));
  222. return LONG_MAX;
  223. }
  224. /* Subtract and round */
  225. mdiff = secdiff*1000 +
  226. /* We add a million usec here to ensure that the result is positive,
  227. * so that the round-towards-zero behavior of the division will give
  228. * the right result for rounding to the nearest msec. Later we subtract
  229. * 1000 in order to get the correct result.
  230. * We'll never get an overflow here, because we check that both usecs are
  231. * between 0 and TV_USEC_PER_SEC. */
  232. ((int64_t)end->tv_usec - (int64_t)start->tv_usec + 500 + 1000000) / 1000
  233. - 1000;
  234. /* Some compilers are smart enough to work out this is a no-op on L64 */
  235. #if SIZEOF_LONG < 8
  236. if (mdiff > (int64_t)LONG_MAX || mdiff < (int64_t)LONG_MIN) {
  237. return LONG_MAX;
  238. }
  239. #endif
  240. return (long)mdiff;
  241. }
  242. /**
  243. * Converts timeval to milliseconds.
  244. */
  245. int64_t
  246. tv_to_msec(const struct timeval *tv)
  247. {
  248. int64_t conv = ((int64_t)tv->tv_sec)*1000L;
  249. /* Round ghetto-style */
  250. conv += ((int64_t)tv->tv_usec+500)/1000L;
  251. return conv;
  252. }
  253. #ifdef _WIN32
  254. HANDLE
  255. load_windows_system_library(const TCHAR *library_name)
  256. {
  257. TCHAR path[MAX_PATH];
  258. unsigned n;
  259. n = GetSystemDirectory(path, MAX_PATH);
  260. if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
  261. return 0;
  262. _tcscat(path, TEXT("\\"));
  263. _tcscat(path, library_name);
  264. return LoadLibrary(path);
  265. }
  266. #endif /* defined(_WIN32) */