map_anon.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file map_anon.c
  7. * \brief Manage anonymous mappings.
  8. **/
  9. #include "orconfig.h"
  10. #include "lib/malloc/map_anon.h"
  11. #include "lib/malloc/malloc.h"
  12. #include "lib/err/torerr.h"
  13. #ifdef HAVE_SYS_MMAN_H
  14. #include <sys/mman.h>
  15. #endif
  16. #ifdef HAVE_SYS_TYPES_H
  17. #include <sys/types.h>
  18. #endif
  19. #ifdef HAVE_MACH_VM_INHERIT_H
  20. #include <mach/vm_inherit.h>
  21. #endif
  22. #ifdef _WIN32
  23. #include <windows.h>
  24. #endif
  25. /**
  26. * Macro to get the high bytes of a size_t, if there are high bytes.
  27. * Windows needs this; other operating systems define a size_t that does
  28. * what it should.
  29. */
  30. #if SIZEOF_SIZE_T > 4
  31. #define HIGH_SIZE_T_BYTES(sz) ((sz) >> 32)
  32. #else
  33. #define HIGH_SIZE_T_BYTES(sz) (0)
  34. #endif
  35. /* Here we define a MINHERIT macro that is minherit() or madvise(), depending
  36. * on what we actually want.
  37. *
  38. * If there's a flag that sets pages to zero after fork, we define FLAG_ZERO
  39. * to be that flag. If there's a flag unmaps pages after fork, we define
  40. * FLAG_NOINHERIT to be that flag.
  41. */
  42. #if defined(HAVE_MINHERIT)
  43. #define MINHERIT minherit
  44. #ifdef INHERIT_ZERO
  45. #define FLAG_ZERO INHERIT_ZERO
  46. #endif
  47. #ifdef INHERIT_NONE
  48. #define FLAG_NOINHERIT INHERIT_NONE
  49. #elif defined(VM_INHERIT_NONE)
  50. #define FLAG_NOINHERIT VM_INHERIT_NONE
  51. #endif
  52. #elif defined(HAVE_MADVISE)
  53. #define MINHERIT madvise
  54. #ifdef MADV_WIPEONFORK
  55. #define FLAG_ZERO MADV_WIPEONFORK
  56. #endif
  57. #ifdef MADV_DONTFORK
  58. #define FLAG_NOINHERIT MADV_DONTFORK
  59. #endif
  60. #endif
  61. /**
  62. * Helper: try to prevent the <b>sz</b> bytes at <b>mem</b> from being swapped
  63. * to disk. Return 0 on success or if the facility is not available on this
  64. * OS; return -1 on failure.
  65. */
  66. static int
  67. lock_mem(void *mem, size_t sz)
  68. {
  69. #ifdef _WIN32
  70. return VirtualLock(mem, sz) ? 0 : -1;
  71. #elif defined(HAVE_MLOCK)
  72. return mlock(mem, sz);
  73. #else
  74. (void) mem;
  75. (void) sz;
  76. return 0;
  77. #endif
  78. }
  79. /**
  80. * Helper: try to prevent the <b>sz</b> bytes at <b>mem</b> from appearing in
  81. * a core dump. Return 0 on success or if the facility is not available on
  82. * this OS; return -1 on failure.
  83. */
  84. static int
  85. nodump_mem(void *mem, size_t sz)
  86. {
  87. #if defined(MADV_DONTDUMP)
  88. return madvise(mem, sz, MADV_DONTDUMP);
  89. #else
  90. (void) mem;
  91. (void) sz;
  92. return 0;
  93. #endif
  94. }
  95. /**
  96. * Helper: try to prevent the <b>sz</b> bytes at <b>mem</b> from being
  97. * accessible in child processes -- ideally by having them set to 0 after a
  98. * fork, and if that doesn't work, by having them unmapped after a fork.
  99. * Return 0 on success or if the facility is not available on this OS; return
  100. * -1 on failure.
  101. */
  102. static int
  103. noinherit_mem(void *mem, size_t sz)
  104. {
  105. #ifdef FLAG_ZERO
  106. int r = MINHERIT(mem, sz, FLAG_ZERO);
  107. if (r == 0)
  108. return 0;
  109. #endif
  110. #ifdef FLAG_NOINHERIT
  111. return MINHERIT(mem, sz, FLAG_NOINHERIT);
  112. #else
  113. (void)mem;
  114. (void)sz;
  115. return 0;
  116. #endif
  117. }
  118. /**
  119. * Return a new anonymous memory mapping that holds <b>sz</b> bytes.
  120. *
  121. * Memory mappings are unlike the results from malloc() in that they are
  122. * handled separately by the operating system, and as such can have different
  123. * kernel-level flags set on them.
  124. *
  125. * The "flags" argument may be zero or more of ANONMAP_PRIVATE and
  126. * ANONMAP_NOINHERIT.
  127. *
  128. * Memory returned from this function must be released with
  129. * tor_munmap_anonymous().
  130. *
  131. * [Note: OS people use the word "anonymous" here to mean that the memory
  132. * isn't associated with any file. This has *nothing* to do with the kind of
  133. * anonymity that Tor is trying to provide.]
  134. */
  135. void *
  136. tor_mmap_anonymous(size_t sz, unsigned flags)
  137. {
  138. void *ptr;
  139. #if defined(_WIN32)
  140. HANDLE mapping = CreateFileMapping(INVALID_HANDLE_VALUE,
  141. NULL, /*attributes*/
  142. PAGE_READWRITE,
  143. HIGH_SIZE_T_BYTES(sz),
  144. sz & 0xffffffff,
  145. NULL /* name */);
  146. raw_assert(mapping != NULL);
  147. ptr = MapViewOfFile(mapping, FILE_MAP_WRITE,
  148. 0, 0, /* Offset */
  149. 0 /* Extend to end of mapping */);
  150. raw_assert(ptr);
  151. CloseHandle(mapping); /* mapped view holds a reference */
  152. #elif defined(HAVE_SYS_MMAN_H)
  153. ptr = mmap(NULL, sz,
  154. PROT_READ|PROT_WRITE,
  155. MAP_ANON|MAP_PRIVATE,
  156. -1, 0);
  157. raw_assert(ptr != MAP_FAILED);
  158. raw_assert(ptr != NULL);
  159. #else
  160. ptr = tor_malloc_zero(sz);
  161. #endif
  162. if (flags & ANONMAP_PRIVATE) {
  163. int lock_result = lock_mem(ptr, sz);
  164. raw_assert(lock_result == 0);
  165. int nodump_result = nodump_mem(ptr, sz);
  166. raw_assert(nodump_result == 0);
  167. }
  168. if (flags & ANONMAP_NOINHERIT) {
  169. int noinherit_result = noinherit_mem(ptr, sz);
  170. raw_assert(noinherit_result == 0);
  171. }
  172. return ptr;
  173. }
  174. /**
  175. * Release <b>sz</b> bytes of memory that were previously mapped at
  176. * <b>mapping</b> by tor_mmap_anonymous().
  177. **/
  178. void
  179. tor_munmap_anonymous(void *mapping, size_t sz)
  180. {
  181. if (!mapping)
  182. return;
  183. #if defined(_WIN32)
  184. (void)sz;
  185. UnmapViewOfFile(mapping);
  186. #elif defined(HAVE_SYS_MMAN_H)
  187. munmap(mapping, sz);
  188. #else
  189. (void)sz;
  190. tor_free(mapping);
  191. #endif
  192. }