msan_linux.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. //===-- msan_linux.cpp ----------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is a part of MemorySanitizer.
  10. //
  11. // Linux-, NetBSD- and FreeBSD-specific code.
  12. //===----------------------------------------------------------------------===//
  13. #include "sanitizer_common/sanitizer_platform.h"
  14. #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
  15. #include "msan.h"
  16. #include "msan_report.h"
  17. #include "msan_thread.h"
  18. #include <elf.h>
  19. #include <link.h>
  20. #include <pthread.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <signal.h>
  24. #include <unistd.h>
  25. #include <unwind.h>
  26. #include <sys/time.h>
  27. #include <sys/resource.h>
  28. #include "sanitizer_common/sanitizer_common.h"
  29. #include "sanitizer_common/sanitizer_procmaps.h"
  30. namespace __msan {
  31. void ReportMapRange(const char *descr, uptr beg, uptr size) {
  32. if (size > 0) {
  33. uptr end = beg + size - 1;
  34. VPrintf(1, "%s : 0x%zx - 0x%zx\n", descr, beg, end);
  35. }
  36. }
  37. static bool CheckMemoryRangeAvailability(uptr beg, uptr size) {
  38. if (size > 0) {
  39. uptr end = beg + size - 1;
  40. if (!MemoryRangeIsAvailable(beg, end)) {
  41. Printf("FATAL: Memory range 0x%zx - 0x%zx is not available.\n", beg, end);
  42. return false;
  43. }
  44. }
  45. return true;
  46. }
  47. static bool ProtectMemoryRange(uptr beg, uptr size, const char *name) {
  48. if (size > 0) {
  49. void *addr = MmapFixedNoAccess(beg, size, name);
  50. if (beg == 0 && addr) {
  51. // Depending on the kernel configuration, we may not be able to protect
  52. // the page at address zero.
  53. uptr gap = 16 * GetPageSizeCached();
  54. beg += gap;
  55. size -= gap;
  56. addr = MmapFixedNoAccess(beg, size, name);
  57. }
  58. if ((uptr)addr != beg) {
  59. uptr end = beg + size - 1;
  60. Printf("FATAL: Cannot protect memory range 0x%zx - 0x%zx (%s).\n", beg,
  61. end, name);
  62. return false;
  63. }
  64. }
  65. return true;
  66. }
  67. static void CheckMemoryLayoutSanity() {
  68. uptr prev_end = 0;
  69. for (unsigned i = 0; i < kMemoryLayoutSize; ++i) {
  70. uptr start = kMemoryLayout[i].start;
  71. uptr end = kMemoryLayout[i].end;
  72. MappingDesc::Type type = kMemoryLayout[i].type;
  73. CHECK_LT(start, end);
  74. CHECK_EQ(prev_end, start);
  75. CHECK(addr_is_type(start, type));
  76. CHECK(addr_is_type((start + end) / 2, type));
  77. CHECK(addr_is_type(end - 1, type));
  78. if (type == MappingDesc::APP) {
  79. uptr addr = start;
  80. CHECK(MEM_IS_SHADOW(MEM_TO_SHADOW(addr)));
  81. CHECK(MEM_IS_ORIGIN(MEM_TO_ORIGIN(addr)));
  82. CHECK_EQ(MEM_TO_ORIGIN(addr), SHADOW_TO_ORIGIN(MEM_TO_SHADOW(addr)));
  83. addr = (start + end) / 2;
  84. CHECK(MEM_IS_SHADOW(MEM_TO_SHADOW(addr)));
  85. CHECK(MEM_IS_ORIGIN(MEM_TO_ORIGIN(addr)));
  86. CHECK_EQ(MEM_TO_ORIGIN(addr), SHADOW_TO_ORIGIN(MEM_TO_SHADOW(addr)));
  87. addr = end - 1;
  88. CHECK(MEM_IS_SHADOW(MEM_TO_SHADOW(addr)));
  89. CHECK(MEM_IS_ORIGIN(MEM_TO_ORIGIN(addr)));
  90. CHECK_EQ(MEM_TO_ORIGIN(addr), SHADOW_TO_ORIGIN(MEM_TO_SHADOW(addr)));
  91. }
  92. prev_end = end;
  93. }
  94. }
  95. bool InitShadow(bool init_origins) {
  96. // Let user know mapping parameters first.
  97. VPrintf(1, "__msan_init %p\n", reinterpret_cast<void *>(&__msan_init));
  98. for (unsigned i = 0; i < kMemoryLayoutSize; ++i)
  99. VPrintf(1, "%s: %zx - %zx\n", kMemoryLayout[i].name, kMemoryLayout[i].start,
  100. kMemoryLayout[i].end - 1);
  101. CheckMemoryLayoutSanity();
  102. if (!MEM_IS_APP(&__msan_init)) {
  103. Printf("FATAL: Code %p is out of application range. Non-PIE build?\n",
  104. reinterpret_cast<void *>(&__msan_init));
  105. return false;
  106. }
  107. const uptr maxVirtualAddress = GetMaxUserVirtualAddress();
  108. for (unsigned i = 0; i < kMemoryLayoutSize; ++i) {
  109. uptr start = kMemoryLayout[i].start;
  110. uptr end = kMemoryLayout[i].end;
  111. uptr size = end - start;
  112. MappingDesc::Type type = kMemoryLayout[i].type;
  113. // Check if the segment should be mapped based on platform constraints.
  114. if (start >= maxVirtualAddress)
  115. continue;
  116. bool map = type == MappingDesc::SHADOW ||
  117. (init_origins && type == MappingDesc::ORIGIN);
  118. bool protect = type == MappingDesc::INVALID ||
  119. (!init_origins && type == MappingDesc::ORIGIN);
  120. CHECK(!(map && protect));
  121. if (!map && !protect)
  122. CHECK(type == MappingDesc::APP);
  123. if (map) {
  124. if (!CheckMemoryRangeAvailability(start, size))
  125. return false;
  126. if (!MmapFixedSuperNoReserve(start, size, kMemoryLayout[i].name))
  127. return false;
  128. if (common_flags()->use_madv_dontdump)
  129. DontDumpShadowMemory(start, size);
  130. }
  131. if (protect) {
  132. if (!CheckMemoryRangeAvailability(start, size))
  133. return false;
  134. if (!ProtectMemoryRange(start, size, kMemoryLayout[i].name))
  135. return false;
  136. }
  137. }
  138. return true;
  139. }
  140. static void MsanAtExit(void) {
  141. if (flags()->print_stats && (flags()->atexit || msan_report_count > 0))
  142. ReportStats();
  143. if (msan_report_count > 0) {
  144. ReportAtExitStatistics();
  145. if (common_flags()->exitcode)
  146. internal__exit(common_flags()->exitcode);
  147. }
  148. }
  149. void InstallAtExitHandler() {
  150. atexit(MsanAtExit);
  151. }
  152. // ---------------------- TSD ---------------- {{{1
  153. #if SANITIZER_NETBSD
  154. // Thread Static Data cannot be used in early init on NetBSD.
  155. // Reuse the MSan TSD API for compatibility with existing code
  156. // with an alternative implementation.
  157. static void (*tsd_destructor)(void *tsd) = nullptr;
  158. struct tsd_key {
  159. tsd_key() : key(nullptr) {}
  160. ~tsd_key() {
  161. CHECK(tsd_destructor);
  162. if (key)
  163. (*tsd_destructor)(key);
  164. }
  165. MsanThread *key;
  166. };
  167. static thread_local struct tsd_key key;
  168. void MsanTSDInit(void (*destructor)(void *tsd)) {
  169. CHECK(!tsd_destructor);
  170. tsd_destructor = destructor;
  171. }
  172. MsanThread *GetCurrentThread() {
  173. CHECK(tsd_destructor);
  174. return key.key;
  175. }
  176. void SetCurrentThread(MsanThread *tsd) {
  177. CHECK(tsd_destructor);
  178. CHECK(tsd);
  179. CHECK(!key.key);
  180. key.key = tsd;
  181. }
  182. void MsanTSDDtor(void *tsd) {
  183. CHECK(tsd_destructor);
  184. CHECK_EQ(key.key, tsd);
  185. key.key = nullptr;
  186. // Make sure that signal handler can not see a stale current thread pointer.
  187. atomic_signal_fence(memory_order_seq_cst);
  188. MsanThread::TSDDtor(tsd);
  189. }
  190. #else
  191. static pthread_key_t tsd_key;
  192. static bool tsd_key_inited = false;
  193. void MsanTSDInit(void (*destructor)(void *tsd)) {
  194. CHECK(!tsd_key_inited);
  195. tsd_key_inited = true;
  196. CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));
  197. }
  198. static THREADLOCAL MsanThread* msan_current_thread;
  199. MsanThread *GetCurrentThread() {
  200. return msan_current_thread;
  201. }
  202. void SetCurrentThread(MsanThread *t) {
  203. // Make sure we do not reset the current MsanThread.
  204. CHECK_EQ(0, msan_current_thread);
  205. msan_current_thread = t;
  206. // Make sure that MsanTSDDtor gets called at the end.
  207. CHECK(tsd_key_inited);
  208. pthread_setspecific(tsd_key, (void *)t);
  209. }
  210. void MsanTSDDtor(void *tsd) {
  211. MsanThread *t = (MsanThread*)tsd;
  212. if (t->destructor_iterations_ > 1) {
  213. t->destructor_iterations_--;
  214. CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));
  215. return;
  216. }
  217. msan_current_thread = nullptr;
  218. // Make sure that signal handler can not see a stale current thread pointer.
  219. atomic_signal_fence(memory_order_seq_cst);
  220. MsanThread::TSDDtor(tsd);
  221. }
  222. #endif
  223. } // namespace __msan
  224. #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD