msan_interceptors.cpp 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797
  1. //===-- msan_interceptors.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. // Interceptors for standard library functions.
  12. //
  13. // FIXME: move as many interceptors as possible into
  14. // sanitizer_common/sanitizer_common_interceptors.h
  15. //===----------------------------------------------------------------------===//
  16. #include "interception/interception.h"
  17. #include "msan.h"
  18. #include "msan_chained_origin_depot.h"
  19. #include "msan_origin.h"
  20. #include "msan_poisoning.h"
  21. #include "msan_report.h"
  22. #include "msan_thread.h"
  23. #include "sanitizer_common/sanitizer_allocator.h"
  24. #include "sanitizer_common/sanitizer_allocator_dlsym.h"
  25. #include "sanitizer_common/sanitizer_allocator_interface.h"
  26. #include "sanitizer_common/sanitizer_atomic.h"
  27. #include "sanitizer_common/sanitizer_common.h"
  28. #include "sanitizer_common/sanitizer_errno.h"
  29. #include "sanitizer_common/sanitizer_errno_codes.h"
  30. #include "sanitizer_common/sanitizer_glibc_version.h"
  31. #include "sanitizer_common/sanitizer_libc.h"
  32. #include "sanitizer_common/sanitizer_linux.h"
  33. #include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
  34. #include "sanitizer_common/sanitizer_platform_limits_posix.h"
  35. #include "sanitizer_common/sanitizer_stackdepot.h"
  36. #include "sanitizer_common/sanitizer_tls_get_addr.h"
  37. #include "sanitizer_common/sanitizer_vector.h"
  38. #if SANITIZER_NETBSD
  39. #define fstat __fstat50
  40. #define gettimeofday __gettimeofday50
  41. #define getrusage __getrusage50
  42. #define tzset __tzset50
  43. #endif
  44. #include <stdarg.h>
  45. // ACHTUNG! No other system header includes in this file.
  46. // Ideally, we should get rid of stdarg.h as well.
  47. using namespace __msan;
  48. using __sanitizer::memory_order;
  49. using __sanitizer::atomic_load;
  50. using __sanitizer::atomic_store;
  51. using __sanitizer::atomic_uintptr_t;
  52. DECLARE_REAL(SIZE_T, strlen, const char *s)
  53. DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen)
  54. DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n)
  55. DECLARE_REAL(void *, memset, void *dest, int c, uptr n)
  56. // True if this is a nested interceptor.
  57. static THREADLOCAL int in_interceptor_scope;
  58. void __msan_scoped_disable_interceptor_checks() { ++in_interceptor_scope; }
  59. void __msan_scoped_enable_interceptor_checks() { --in_interceptor_scope; }
  60. struct InterceptorScope {
  61. InterceptorScope() { ++in_interceptor_scope; }
  62. ~InterceptorScope() { --in_interceptor_scope; }
  63. };
  64. bool IsInInterceptorScope() {
  65. return in_interceptor_scope;
  66. }
  67. struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
  68. static bool UseImpl() { return !msan_inited; }
  69. };
  70. #define ENSURE_MSAN_INITED() do { \
  71. CHECK(!msan_init_is_running); \
  72. if (!msan_inited) { \
  73. __msan_init(); \
  74. } \
  75. } while (0)
  76. // Check that [x, x+n) range is unpoisoned.
  77. #define CHECK_UNPOISONED_0(x, n) \
  78. do { \
  79. sptr __offset = __msan_test_shadow(x, n); \
  80. if (__msan::IsInSymbolizerOrUnwider()) \
  81. break; \
  82. if (__offset >= 0 && __msan::flags()->report_umrs) { \
  83. GET_CALLER_PC_BP_SP; \
  84. (void)sp; \
  85. ReportUMRInsideAddressRange(__func__, x, n, __offset); \
  86. __msan::PrintWarningWithOrigin( \
  87. pc, bp, __msan_get_origin((const char *)x + __offset)); \
  88. if (__msan::flags()->halt_on_error) { \
  89. Printf("Exiting\n"); \
  90. Die(); \
  91. } \
  92. } \
  93. } while (0)
  94. // Check that [x, x+n) range is unpoisoned unless we are in a nested
  95. // interceptor.
  96. #define CHECK_UNPOISONED(x, n) \
  97. do { \
  98. if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \
  99. } while (0)
  100. #define CHECK_UNPOISONED_STRING_OF_LEN(x, len, n) \
  101. CHECK_UNPOISONED((x), \
  102. common_flags()->strict_string_checks ? (len) + 1 : (n) )
  103. #define CHECK_UNPOISONED_STRING(x, n) \
  104. CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n))
  105. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  106. INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
  107. void *file) {
  108. ENSURE_MSAN_INITED();
  109. SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);
  110. if (res > 0)
  111. __msan_unpoison(ptr, res *size);
  112. return res;
  113. }
  114. #define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED INTERCEPT_FUNCTION(fread_unlocked)
  115. #else
  116. #define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED
  117. #endif
  118. #if !SANITIZER_NETBSD
  119. INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
  120. return (char *)__msan_memcpy(dest, src, n) + n;
  121. }
  122. #define MSAN_MAYBE_INTERCEPT_MEMPCPY INTERCEPT_FUNCTION(mempcpy)
  123. #else
  124. #define MSAN_MAYBE_INTERCEPT_MEMPCPY
  125. #endif
  126. INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {
  127. ENSURE_MSAN_INITED();
  128. void *res = REAL(memccpy)(dest, src, c, n);
  129. CHECK(!res || (res >= dest && res <= (char *)dest + n));
  130. SIZE_T sz = res ? (char *)res - (char *)dest : n;
  131. CHECK_UNPOISONED(src, sz);
  132. __msan_unpoison(dest, sz);
  133. return res;
  134. }
  135. INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {
  136. return __msan_memmove(dest, src, n);
  137. }
  138. INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
  139. GET_MALLOC_STACK_TRACE;
  140. CHECK_NE(memptr, 0);
  141. int res = msan_posix_memalign(memptr, alignment, size, &stack);
  142. if (!res)
  143. __msan_unpoison(memptr, sizeof(*memptr));
  144. return res;
  145. }
  146. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  147. INTERCEPTOR(void *, memalign, SIZE_T alignment, SIZE_T size) {
  148. GET_MALLOC_STACK_TRACE;
  149. return msan_memalign(alignment, size, &stack);
  150. }
  151. #define MSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
  152. #else
  153. #define MSAN_MAYBE_INTERCEPT_MEMALIGN
  154. #endif
  155. INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
  156. GET_MALLOC_STACK_TRACE;
  157. return msan_aligned_alloc(alignment, size, &stack);
  158. }
  159. #if !SANITIZER_NETBSD
  160. INTERCEPTOR(void *, __libc_memalign, SIZE_T alignment, SIZE_T size) {
  161. GET_MALLOC_STACK_TRACE;
  162. void *ptr = msan_memalign(alignment, size, &stack);
  163. if (ptr)
  164. DTLS_on_libc_memalign(ptr, size);
  165. return ptr;
  166. }
  167. #define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)
  168. #else
  169. #define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
  170. #endif
  171. INTERCEPTOR(void *, valloc, SIZE_T size) {
  172. GET_MALLOC_STACK_TRACE;
  173. return msan_valloc(size, &stack);
  174. }
  175. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  176. INTERCEPTOR(void *, pvalloc, SIZE_T size) {
  177. GET_MALLOC_STACK_TRACE;
  178. return msan_pvalloc(size, &stack);
  179. }
  180. #define MSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
  181. #else
  182. #define MSAN_MAYBE_INTERCEPT_PVALLOC
  183. #endif
  184. INTERCEPTOR(void, free, void *ptr) {
  185. if (UNLIKELY(!ptr))
  186. return;
  187. if (DlsymAlloc::PointerIsMine(ptr))
  188. return DlsymAlloc::Free(ptr);
  189. GET_MALLOC_STACK_TRACE;
  190. MsanDeallocate(&stack, ptr);
  191. }
  192. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  193. INTERCEPTOR(void, cfree, void *ptr) {
  194. if (UNLIKELY(!ptr))
  195. return;
  196. if (DlsymAlloc::PointerIsMine(ptr))
  197. return DlsymAlloc::Free(ptr);
  198. GET_MALLOC_STACK_TRACE;
  199. MsanDeallocate(&stack, ptr);
  200. }
  201. # define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)
  202. #else
  203. #define MSAN_MAYBE_INTERCEPT_CFREE
  204. #endif
  205. #if !SANITIZER_NETBSD
  206. INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
  207. return __sanitizer_get_allocated_size(ptr);
  208. }
  209. #define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE \
  210. INTERCEPT_FUNCTION(malloc_usable_size)
  211. #else
  212. #define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE
  213. #endif
  214. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  215. // This function actually returns a struct by value, but we can't unpoison a
  216. // temporary! The following is equivalent on all supported platforms but
  217. // aarch64 (which uses a different register for sret value). We have a test
  218. // to confirm that.
  219. INTERCEPTOR(void, mallinfo, __sanitizer_struct_mallinfo *sret) {
  220. #ifdef __aarch64__
  221. uptr r8;
  222. asm volatile("mov %0,x8" : "=r" (r8));
  223. sret = reinterpret_cast<__sanitizer_struct_mallinfo*>(r8);
  224. #endif
  225. REAL(memset)(sret, 0, sizeof(*sret));
  226. __msan_unpoison(sret, sizeof(*sret));
  227. }
  228. #define MSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)
  229. #else
  230. #define MSAN_MAYBE_INTERCEPT_MALLINFO
  231. #endif
  232. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  233. INTERCEPTOR(int, mallopt, int cmd, int value) {
  234. return 0;
  235. }
  236. #define MSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)
  237. #else
  238. #define MSAN_MAYBE_INTERCEPT_MALLOPT
  239. #endif
  240. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  241. INTERCEPTOR(void, malloc_stats, void) {
  242. // FIXME: implement, but don't call REAL(malloc_stats)!
  243. }
  244. #define MSAN_MAYBE_INTERCEPT_MALLOC_STATS INTERCEPT_FUNCTION(malloc_stats)
  245. #else
  246. #define MSAN_MAYBE_INTERCEPT_MALLOC_STATS
  247. #endif
  248. INTERCEPTOR(char *, strcpy, char *dest, const char *src) {
  249. ENSURE_MSAN_INITED();
  250. GET_STORE_STACK_TRACE;
  251. SIZE_T n = internal_strlen(src);
  252. CHECK_UNPOISONED_STRING(src + n, 0);
  253. char *res = REAL(strcpy)(dest, src);
  254. CopyShadowAndOrigin(dest, src, n + 1, &stack);
  255. return res;
  256. }
  257. INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {
  258. ENSURE_MSAN_INITED();
  259. GET_STORE_STACK_TRACE;
  260. SIZE_T copy_size = internal_strnlen(src, n);
  261. if (copy_size < n)
  262. copy_size++; // trailing \0
  263. char *res = REAL(strncpy)(dest, src, n);
  264. CopyShadowAndOrigin(dest, src, copy_size, &stack);
  265. __msan_unpoison(dest + copy_size, n - copy_size);
  266. return res;
  267. }
  268. #if !SANITIZER_NETBSD
  269. INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {
  270. ENSURE_MSAN_INITED();
  271. GET_STORE_STACK_TRACE;
  272. SIZE_T n = internal_strlen(src);
  273. CHECK_UNPOISONED_STRING(src + n, 0);
  274. char *res = REAL(stpcpy)(dest, src);
  275. CopyShadowAndOrigin(dest, src, n + 1, &stack);
  276. return res;
  277. }
  278. INTERCEPTOR(char *, stpncpy, char *dest, const char *src, SIZE_T n) {
  279. ENSURE_MSAN_INITED();
  280. GET_STORE_STACK_TRACE;
  281. SIZE_T copy_size = Min(n, internal_strnlen(src, n) + 1);
  282. char *res = REAL(stpncpy)(dest, src, n);
  283. CopyShadowAndOrigin(dest, src, copy_size, &stack);
  284. __msan_unpoison(dest + copy_size, n - copy_size);
  285. return res;
  286. }
  287. # define MSAN_MAYBE_INTERCEPT_STPCPY INTERCEPT_FUNCTION(stpcpy)
  288. # define MSAN_MAYBE_INTERCEPT_STPNCPY INTERCEPT_FUNCTION(stpncpy)
  289. #else
  290. #define MSAN_MAYBE_INTERCEPT_STPCPY
  291. # define MSAN_MAYBE_INTERCEPT_STPNCPY
  292. #endif
  293. INTERCEPTOR(char *, strdup, char *src) {
  294. ENSURE_MSAN_INITED();
  295. GET_STORE_STACK_TRACE;
  296. // On FreeBSD strdup() leverages strlen().
  297. InterceptorScope interceptor_scope;
  298. SIZE_T n = internal_strlen(src);
  299. CHECK_UNPOISONED_STRING(src + n, 0);
  300. char *res = REAL(strdup)(src);
  301. CopyShadowAndOrigin(res, src, n + 1, &stack);
  302. return res;
  303. }
  304. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  305. INTERCEPTOR(char *, __strdup, char *src) {
  306. ENSURE_MSAN_INITED();
  307. GET_STORE_STACK_TRACE;
  308. SIZE_T n = internal_strlen(src);
  309. CHECK_UNPOISONED_STRING(src + n, 0);
  310. char *res = REAL(__strdup)(src);
  311. CopyShadowAndOrigin(res, src, n + 1, &stack);
  312. return res;
  313. }
  314. #define MSAN_MAYBE_INTERCEPT___STRDUP INTERCEPT_FUNCTION(__strdup)
  315. #else
  316. #define MSAN_MAYBE_INTERCEPT___STRDUP
  317. #endif
  318. #if !SANITIZER_NETBSD
  319. INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
  320. ENSURE_MSAN_INITED();
  321. char *res = REAL(gcvt)(number, ndigit, buf);
  322. SIZE_T n = internal_strlen(buf);
  323. __msan_unpoison(buf, n + 1);
  324. return res;
  325. }
  326. #define MSAN_MAYBE_INTERCEPT_GCVT INTERCEPT_FUNCTION(gcvt)
  327. #else
  328. #define MSAN_MAYBE_INTERCEPT_GCVT
  329. #endif
  330. INTERCEPTOR(char *, strcat, char *dest, const char *src) {
  331. ENSURE_MSAN_INITED();
  332. GET_STORE_STACK_TRACE;
  333. SIZE_T src_size = internal_strlen(src);
  334. SIZE_T dest_size = internal_strlen(dest);
  335. CHECK_UNPOISONED_STRING(src + src_size, 0);
  336. CHECK_UNPOISONED_STRING(dest + dest_size, 0);
  337. char *res = REAL(strcat)(dest, src);
  338. CopyShadowAndOrigin(dest + dest_size, src, src_size + 1, &stack);
  339. return res;
  340. }
  341. INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {
  342. ENSURE_MSAN_INITED();
  343. GET_STORE_STACK_TRACE;
  344. SIZE_T dest_size = internal_strlen(dest);
  345. SIZE_T copy_size = internal_strnlen(src, n);
  346. CHECK_UNPOISONED_STRING(dest + dest_size, 0);
  347. char *res = REAL(strncat)(dest, src, n);
  348. CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack);
  349. __msan_unpoison(dest + dest_size + copy_size, 1); // \0
  350. return res;
  351. }
  352. // Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to
  353. // deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO.
  354. #define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \
  355. ENSURE_MSAN_INITED(); \
  356. ret_type res = REAL(func)(__VA_ARGS__); \
  357. __msan_unpoison(endptr, sizeof(*endptr)); \
  358. return res;
  359. #define INTERCEPTOR_STRTO(ret_type, func, char_type) \
  360. INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr) { \
  361. INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr); \
  362. }
  363. #define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \
  364. INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
  365. int base) { \
  366. INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base); \
  367. }
  368. #define INTERCEPTOR_STRTO_LOC(ret_type, func, char_type) \
  369. INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
  370. void *loc) { \
  371. INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc); \
  372. }
  373. #define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type) \
  374. INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
  375. int base, void *loc) { \
  376. INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc); \
  377. }
  378. #if SANITIZER_NETBSD
  379. #define INTERCEPTORS_STRTO(ret_type, func, char_type) \
  380. INTERCEPTOR_STRTO(ret_type, func, char_type) \
  381. INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type)
  382. #define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \
  383. INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \
  384. INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type)
  385. #else
  386. #define INTERCEPTORS_STRTO(ret_type, func, char_type) \
  387. INTERCEPTOR_STRTO(ret_type, func, char_type) \
  388. INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type) \
  389. INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \
  390. INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type)
  391. #define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \
  392. INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \
  393. INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type) \
  394. INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_l, char_type) \
  395. INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_internal, char_type)
  396. #endif
  397. INTERCEPTORS_STRTO(double, strtod, char)
  398. INTERCEPTORS_STRTO(float, strtof, char)
  399. INTERCEPTORS_STRTO(long double, strtold, char)
  400. INTERCEPTORS_STRTO_BASE(long, strtol, char)
  401. INTERCEPTORS_STRTO_BASE(long long, strtoll, char)
  402. INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char)
  403. INTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char)
  404. INTERCEPTORS_STRTO_BASE(u64, strtouq, char)
  405. INTERCEPTORS_STRTO(double, wcstod, wchar_t)
  406. INTERCEPTORS_STRTO(float, wcstof, wchar_t)
  407. INTERCEPTORS_STRTO(long double, wcstold, wchar_t)
  408. INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t)
  409. INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t)
  410. INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t)
  411. INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t)
  412. #if SANITIZER_NETBSD
  413. #define INTERCEPT_STRTO(func) \
  414. INTERCEPT_FUNCTION(func); \
  415. INTERCEPT_FUNCTION(func##_l);
  416. #else
  417. #define INTERCEPT_STRTO(func) \
  418. INTERCEPT_FUNCTION(func); \
  419. INTERCEPT_FUNCTION(func##_l); \
  420. INTERCEPT_FUNCTION(__##func##_l); \
  421. INTERCEPT_FUNCTION(__##func##_internal);
  422. #endif
  423. // FIXME: support *wprintf in common format interceptors.
  424. INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
  425. ENSURE_MSAN_INITED();
  426. int res = REAL(vswprintf)(str, size, format, ap);
  427. if (res >= 0) {
  428. __msan_unpoison(str, 4 * (res + 1));
  429. }
  430. return res;
  431. }
  432. INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {
  433. ENSURE_MSAN_INITED();
  434. va_list ap;
  435. va_start(ap, format);
  436. int res = vswprintf(str, size, format, ap);
  437. va_end(ap);
  438. return res;
  439. }
  440. #define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \
  441. ENSURE_MSAN_INITED(); \
  442. InterceptorScope interceptor_scope; \
  443. ret_type res = REAL(func)(s, __VA_ARGS__); \
  444. if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1)); \
  445. return res;
  446. INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,
  447. __sanitizer_tm *tm) {
  448. INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime, s, max, format, tm);
  449. }
  450. INTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,
  451. __sanitizer_tm *tm, void *loc) {
  452. INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);
  453. }
  454. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  455. INTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,
  456. __sanitizer_tm *tm, void *loc) {
  457. INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm,
  458. loc);
  459. }
  460. #define MSAN_MAYBE_INTERCEPT___STRFTIME_L INTERCEPT_FUNCTION(__strftime_l)
  461. #else
  462. #define MSAN_MAYBE_INTERCEPT___STRFTIME_L
  463. #endif
  464. INTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format,
  465. __sanitizer_tm *tm) {
  466. INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime, s, max, format, tm);
  467. }
  468. INTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
  469. __sanitizer_tm *tm, void *loc) {
  470. INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime_l, s, max, format, tm,
  471. loc);
  472. }
  473. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  474. INTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
  475. __sanitizer_tm *tm, void *loc) {
  476. INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm,
  477. loc);
  478. }
  479. #define MSAN_MAYBE_INTERCEPT___WCSFTIME_L INTERCEPT_FUNCTION(__wcsftime_l)
  480. #else
  481. #define MSAN_MAYBE_INTERCEPT___WCSFTIME_L
  482. #endif
  483. INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
  484. ENSURE_MSAN_INITED();
  485. int res = REAL(mbtowc)(dest, src, n);
  486. if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
  487. return res;
  488. }
  489. INTERCEPTOR(SIZE_T, mbrtowc, wchar_t *dest, const char *src, SIZE_T n,
  490. void *ps) {
  491. ENSURE_MSAN_INITED();
  492. SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);
  493. if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
  494. return res;
  495. }
  496. // wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
  497. INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
  498. ENSURE_MSAN_INITED();
  499. GET_STORE_STACK_TRACE;
  500. wchar_t *res = REAL(wmemcpy)(dest, src, n);
  501. CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
  502. return res;
  503. }
  504. #if !SANITIZER_NETBSD
  505. INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
  506. ENSURE_MSAN_INITED();
  507. GET_STORE_STACK_TRACE;
  508. wchar_t *res = REAL(wmempcpy)(dest, src, n);
  509. CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
  510. return res;
  511. }
  512. #define MSAN_MAYBE_INTERCEPT_WMEMPCPY INTERCEPT_FUNCTION(wmempcpy)
  513. #else
  514. #define MSAN_MAYBE_INTERCEPT_WMEMPCPY
  515. #endif
  516. INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
  517. CHECK(MEM_IS_APP(s));
  518. ENSURE_MSAN_INITED();
  519. wchar_t *res = REAL(wmemset)(s, c, n);
  520. __msan_unpoison(s, n * sizeof(wchar_t));
  521. return res;
  522. }
  523. INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {
  524. ENSURE_MSAN_INITED();
  525. GET_STORE_STACK_TRACE;
  526. wchar_t *res = REAL(wmemmove)(dest, src, n);
  527. MoveShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
  528. return res;
  529. }
  530. INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {
  531. ENSURE_MSAN_INITED();
  532. int res = REAL(wcscmp)(s1, s2);
  533. return res;
  534. }
  535. INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
  536. ENSURE_MSAN_INITED();
  537. int res = REAL(gettimeofday)(tv, tz);
  538. if (tv)
  539. __msan_unpoison(tv, 16);
  540. if (tz)
  541. __msan_unpoison(tz, 8);
  542. return res;
  543. }
  544. #if !SANITIZER_NETBSD
  545. INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
  546. ENSURE_MSAN_INITED();
  547. char *res = REAL(fcvt)(x, a, b, c);
  548. __msan_unpoison(b, sizeof(*b));
  549. __msan_unpoison(c, sizeof(*c));
  550. if (res)
  551. __msan_unpoison(res, internal_strlen(res) + 1);
  552. return res;
  553. }
  554. #define MSAN_MAYBE_INTERCEPT_FCVT INTERCEPT_FUNCTION(fcvt)
  555. #else
  556. #define MSAN_MAYBE_INTERCEPT_FCVT
  557. #endif
  558. INTERCEPTOR(char *, getenv, char *name) {
  559. if (msan_init_is_running)
  560. return REAL(getenv)(name);
  561. ENSURE_MSAN_INITED();
  562. char *res = REAL(getenv)(name);
  563. if (res)
  564. __msan_unpoison(res, internal_strlen(res) + 1);
  565. return res;
  566. }
  567. extern char **environ;
  568. static void UnpoisonEnviron() {
  569. char **envp = environ;
  570. for (; *envp; ++envp) {
  571. __msan_unpoison(envp, sizeof(*envp));
  572. __msan_unpoison(*envp, internal_strlen(*envp) + 1);
  573. }
  574. // Trailing NULL pointer.
  575. __msan_unpoison(envp, sizeof(*envp));
  576. }
  577. INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {
  578. ENSURE_MSAN_INITED();
  579. CHECK_UNPOISONED_STRING(name, 0);
  580. int res = REAL(setenv)(name, value, overwrite);
  581. if (!res) UnpoisonEnviron();
  582. return res;
  583. }
  584. INTERCEPTOR(int, putenv, char *string) {
  585. ENSURE_MSAN_INITED();
  586. int res = REAL(putenv)(string);
  587. if (!res) UnpoisonEnviron();
  588. return res;
  589. }
  590. #define SANITIZER_STAT_LINUX (SANITIZER_LINUX && __GLIBC_PREREQ(2, 33))
  591. #if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX
  592. INTERCEPTOR(int, fstat, int fd, void *buf) {
  593. ENSURE_MSAN_INITED();
  594. int res = REAL(fstat)(fd, buf);
  595. if (!res)
  596. __msan_unpoison(buf, __sanitizer::struct_stat_sz);
  597. return res;
  598. }
  599. # define MSAN_MAYBE_INTERCEPT_FSTAT MSAN_INTERCEPT_FUNC(fstat)
  600. #else
  601. #define MSAN_MAYBE_INTERCEPT_FSTAT
  602. #endif
  603. #if SANITIZER_STAT_LINUX
  604. INTERCEPTOR(int, fstat64, int fd, void *buf) {
  605. ENSURE_MSAN_INITED();
  606. int res = REAL(fstat64)(fd, buf);
  607. if (!res)
  608. __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
  609. return res;
  610. }
  611. # define MSAN_MAYBE_INTERCEPT_FSTAT64 MSAN_INTERCEPT_FUNC(fstat64)
  612. #else
  613. # define MSAN_MAYBE_INTERCEPT_FSTAT64
  614. #endif
  615. #if SANITIZER_GLIBC
  616. INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
  617. ENSURE_MSAN_INITED();
  618. int res = REAL(__fxstat)(magic, fd, buf);
  619. if (!res)
  620. __msan_unpoison(buf, __sanitizer::struct_stat_sz);
  621. return res;
  622. }
  623. # define MSAN_MAYBE_INTERCEPT___FXSTAT MSAN_INTERCEPT_FUNC(__fxstat)
  624. #else
  625. #define MSAN_MAYBE_INTERCEPT___FXSTAT
  626. #endif
  627. #if SANITIZER_GLIBC
  628. INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
  629. ENSURE_MSAN_INITED();
  630. int res = REAL(__fxstat64)(magic, fd, buf);
  631. if (!res)
  632. __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
  633. return res;
  634. }
  635. # define MSAN_MAYBE_INTERCEPT___FXSTAT64 MSAN_INTERCEPT_FUNC(__fxstat64)
  636. #else
  637. # define MSAN_MAYBE_INTERCEPT___FXSTAT64
  638. #endif
  639. #if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX
  640. INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {
  641. ENSURE_MSAN_INITED();
  642. int res = REAL(fstatat)(fd, pathname, buf, flags);
  643. if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
  644. return res;
  645. }
  646. # define MSAN_MAYBE_INTERCEPT_FSTATAT MSAN_INTERCEPT_FUNC(fstatat)
  647. #else
  648. # define MSAN_MAYBE_INTERCEPT_FSTATAT
  649. #endif
  650. #if SANITIZER_STAT_LINUX
  651. INTERCEPTOR(int, fstatat64, int fd, char *pathname, void *buf, int flags) {
  652. ENSURE_MSAN_INITED();
  653. int res = REAL(fstatat64)(fd, pathname, buf, flags);
  654. if (!res)
  655. __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
  656. return res;
  657. }
  658. # define MSAN_MAYBE_INTERCEPT_FSTATAT64 MSAN_INTERCEPT_FUNC(fstatat64)
  659. #else
  660. # define MSAN_MAYBE_INTERCEPT_FSTATAT64
  661. #endif
  662. #if SANITIZER_GLIBC
  663. INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
  664. int flags) {
  665. ENSURE_MSAN_INITED();
  666. int res = REAL(__fxstatat)(magic, fd, pathname, buf, flags);
  667. if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
  668. return res;
  669. }
  670. # define MSAN_MAYBE_INTERCEPT___FXSTATAT MSAN_INTERCEPT_FUNC(__fxstatat)
  671. #else
  672. # define MSAN_MAYBE_INTERCEPT___FXSTATAT
  673. #endif
  674. #if SANITIZER_GLIBC
  675. INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,
  676. int flags) {
  677. ENSURE_MSAN_INITED();
  678. int res = REAL(__fxstatat64)(magic, fd, pathname, buf, flags);
  679. if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
  680. return res;
  681. }
  682. # define MSAN_MAYBE_INTERCEPT___FXSTATAT64 MSAN_INTERCEPT_FUNC(__fxstatat64)
  683. #else
  684. # define MSAN_MAYBE_INTERCEPT___FXSTATAT64
  685. #endif
  686. INTERCEPTOR(int, pipe, int pipefd[2]) {
  687. if (msan_init_is_running)
  688. return REAL(pipe)(pipefd);
  689. ENSURE_MSAN_INITED();
  690. int res = REAL(pipe)(pipefd);
  691. if (!res)
  692. __msan_unpoison(pipefd, sizeof(int[2]));
  693. return res;
  694. }
  695. INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
  696. ENSURE_MSAN_INITED();
  697. int res = REAL(pipe2)(pipefd, flags);
  698. if (!res)
  699. __msan_unpoison(pipefd, sizeof(int[2]));
  700. return res;
  701. }
  702. INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {
  703. ENSURE_MSAN_INITED();
  704. int res = REAL(socketpair)(domain, type, protocol, sv);
  705. if (!res)
  706. __msan_unpoison(sv, sizeof(int[2]));
  707. return res;
  708. }
  709. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  710. INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
  711. ENSURE_MSAN_INITED();
  712. char *res = REAL(fgets_unlocked)(s, size, stream);
  713. if (res)
  714. __msan_unpoison(s, internal_strlen(s) + 1);
  715. return res;
  716. }
  717. #define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED INTERCEPT_FUNCTION(fgets_unlocked)
  718. #else
  719. #define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED
  720. #endif
  721. #define INTERCEPTOR_GETRLIMIT_BODY(func, resource, rlim) \
  722. if (msan_init_is_running) \
  723. return REAL(getrlimit)(resource, rlim); \
  724. ENSURE_MSAN_INITED(); \
  725. int res = REAL(func)(resource, rlim); \
  726. if (!res) \
  727. __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz); \
  728. return res
  729. INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
  730. INTERCEPTOR_GETRLIMIT_BODY(getrlimit, resource, rlim);
  731. }
  732. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  733. INTERCEPTOR(int, __getrlimit, int resource, void *rlim) {
  734. INTERCEPTOR_GETRLIMIT_BODY(__getrlimit, resource, rlim);
  735. }
  736. INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
  737. if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim);
  738. ENSURE_MSAN_INITED();
  739. int res = REAL(getrlimit64)(resource, rlim);
  740. if (!res) __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);
  741. return res;
  742. }
  743. INTERCEPTOR(int, prlimit, int pid, int resource, void *new_rlimit,
  744. void *old_rlimit) {
  745. if (msan_init_is_running)
  746. return REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);
  747. ENSURE_MSAN_INITED();
  748. CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit_sz);
  749. int res = REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);
  750. if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit_sz);
  751. return res;
  752. }
  753. INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit,
  754. void *old_rlimit) {
  755. if (msan_init_is_running)
  756. return REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);
  757. ENSURE_MSAN_INITED();
  758. CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit64_sz);
  759. int res = REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);
  760. if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit64_sz);
  761. return res;
  762. }
  763. #define MSAN_MAYBE_INTERCEPT___GETRLIMIT INTERCEPT_FUNCTION(__getrlimit)
  764. #define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64)
  765. #define MSAN_MAYBE_INTERCEPT_PRLIMIT INTERCEPT_FUNCTION(prlimit)
  766. #define MSAN_MAYBE_INTERCEPT_PRLIMIT64 INTERCEPT_FUNCTION(prlimit64)
  767. #else
  768. #define MSAN_MAYBE_INTERCEPT___GETRLIMIT
  769. #define MSAN_MAYBE_INTERCEPT_GETRLIMIT64
  770. #define MSAN_MAYBE_INTERCEPT_PRLIMIT
  771. #define MSAN_MAYBE_INTERCEPT_PRLIMIT64
  772. #endif
  773. INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
  774. ENSURE_MSAN_INITED();
  775. int res = REAL(gethostname)(name, len);
  776. if (!res || (res == -1 && errno == errno_ENAMETOOLONG)) {
  777. SIZE_T real_len = internal_strnlen(name, len);
  778. if (real_len < len)
  779. ++real_len;
  780. __msan_unpoison(name, real_len);
  781. }
  782. return res;
  783. }
  784. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  785. INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
  786. int timeout) {
  787. ENSURE_MSAN_INITED();
  788. int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);
  789. if (res > 0) {
  790. __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
  791. }
  792. return res;
  793. }
  794. #define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION(epoll_wait)
  795. #else
  796. #define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT
  797. #endif
  798. #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
  799. INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
  800. int timeout, void *sigmask) {
  801. ENSURE_MSAN_INITED();
  802. int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
  803. if (res > 0) {
  804. __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
  805. }
  806. return res;
  807. }
  808. #define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION(epoll_pwait)
  809. #else
  810. #define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
  811. #endif
  812. INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
  813. GET_MALLOC_STACK_TRACE;
  814. if (DlsymAlloc::Use())
  815. return DlsymAlloc::Callocate(nmemb, size);
  816. return msan_calloc(nmemb, size, &stack);
  817. }
  818. INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
  819. if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
  820. return DlsymAlloc::Realloc(ptr, size);
  821. GET_MALLOC_STACK_TRACE;
  822. return msan_realloc(ptr, size, &stack);
  823. }
  824. INTERCEPTOR(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size) {
  825. GET_MALLOC_STACK_TRACE;
  826. return msan_reallocarray(ptr, nmemb, size, &stack);
  827. }
  828. INTERCEPTOR(void *, malloc, SIZE_T size) {
  829. if (DlsymAlloc::Use())
  830. return DlsymAlloc::Allocate(size);
  831. GET_MALLOC_STACK_TRACE;
  832. return msan_malloc(size, &stack);
  833. }
  834. void __msan_allocated_memory(const void *data, uptr size) {
  835. if (flags()->poison_in_malloc) {
  836. GET_MALLOC_STACK_TRACE;
  837. stack.tag = STACK_TRACE_TAG_POISON;
  838. PoisonMemory(data, size, &stack);
  839. }
  840. }
  841. void __msan_copy_shadow(void *dest, const void *src, uptr n) {
  842. GET_STORE_STACK_TRACE;
  843. MoveShadowAndOrigin(dest, src, n, &stack);
  844. }
  845. void __sanitizer_dtor_callback(const void *data, uptr size) {
  846. if (flags()->poison_in_dtor) {
  847. GET_MALLOC_STACK_TRACE;
  848. stack.tag = STACK_TRACE_TAG_POISON;
  849. PoisonMemory(data, size, &stack);
  850. }
  851. }
  852. void __sanitizer_dtor_callback_fields(const void *data, uptr size) {
  853. if (flags()->poison_in_dtor) {
  854. GET_MALLOC_STACK_TRACE;
  855. stack.tag = STACK_TRACE_TAG_FIELDS;
  856. PoisonMemory(data, size, &stack);
  857. }
  858. }
  859. void __sanitizer_dtor_callback_vptr(const void *data) {
  860. if (flags()->poison_in_dtor) {
  861. GET_MALLOC_STACK_TRACE;
  862. stack.tag = STACK_TRACE_TAG_VPTR;
  863. PoisonMemory(data, sizeof(void *), &stack);
  864. }
  865. }
  866. template <class Mmap>
  867. static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
  868. int prot, int flags, int fd, OFF64_T offset) {
  869. SIZE_T rounded_length = RoundUpTo(length, GetPageSize());
  870. void *end_addr = (char *)addr + (rounded_length - 1);
  871. if (addr && (!MEM_IS_APP(addr) || !MEM_IS_APP(end_addr))) {
  872. if (flags & map_fixed) {
  873. errno = errno_EINVAL;
  874. return (void *)-1;
  875. } else {
  876. addr = nullptr;
  877. }
  878. }
  879. void *res = real_mmap(addr, length, prot, flags, fd, offset);
  880. if (res != (void *)-1) {
  881. void *end_res = (char *)res + (rounded_length - 1);
  882. if (MEM_IS_APP(res) && MEM_IS_APP(end_res)) {
  883. __msan_unpoison(res, rounded_length);
  884. } else {
  885. // Application has attempted to map more memory than is supported by
  886. // MSAN. Act as if we ran out of memory.
  887. internal_munmap(res, length);
  888. errno = errno_ENOMEM;
  889. return (void *)-1;
  890. }
  891. }
  892. return res;
  893. }
  894. INTERCEPTOR(int, getrusage, int who, void *usage) {
  895. ENSURE_MSAN_INITED();
  896. int res = REAL(getrusage)(who, usage);
  897. if (res == 0) {
  898. __msan_unpoison(usage, __sanitizer::struct_rusage_sz);
  899. }
  900. return res;
  901. }
  902. class SignalHandlerScope {
  903. public:
  904. SignalHandlerScope() {
  905. if (MsanThread *t = GetCurrentThread())
  906. t->EnterSignalHandler();
  907. }
  908. ~SignalHandlerScope() {
  909. if (MsanThread *t = GetCurrentThread())
  910. t->LeaveSignalHandler();
  911. }
  912. };
  913. // sigactions_mu guarantees atomicity of sigaction() and signal() calls.
  914. // Access to sigactions[] is gone with relaxed atomics to avoid data race with
  915. // the signal handler.
  916. const int kMaxSignals = 1024;
  917. static atomic_uintptr_t sigactions[kMaxSignals];
  918. static StaticSpinMutex sigactions_mu;
  919. static void SignalHandler(int signo) {
  920. SignalHandlerScope signal_handler_scope;
  921. ScopedThreadLocalStateBackup stlsb;
  922. UnpoisonParam(1);
  923. typedef void (*signal_cb)(int x);
  924. signal_cb cb =
  925. (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
  926. cb(signo);
  927. }
  928. static void SignalAction(int signo, void *si, void *uc) {
  929. SignalHandlerScope signal_handler_scope;
  930. ScopedThreadLocalStateBackup stlsb;
  931. UnpoisonParam(3);
  932. __msan_unpoison(si, sizeof(__sanitizer_sigaction));
  933. __msan_unpoison(uc, ucontext_t_sz(uc));
  934. typedef void (*sigaction_cb)(int, void *, void *);
  935. sigaction_cb cb =
  936. (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
  937. cb(signo, si, uc);
  938. CHECK_UNPOISONED(uc, ucontext_t_sz(uc));
  939. }
  940. static void read_sigaction(const __sanitizer_sigaction *act) {
  941. CHECK_UNPOISONED(&act->sa_flags, sizeof(act->sa_flags));
  942. if (act->sa_flags & __sanitizer::sa_siginfo)
  943. CHECK_UNPOISONED(&act->sigaction, sizeof(act->sigaction));
  944. else
  945. CHECK_UNPOISONED(&act->handler, sizeof(act->handler));
  946. CHECK_UNPOISONED(&act->sa_mask, sizeof(act->sa_mask));
  947. }
  948. extern "C" int pthread_attr_init(void *attr);
  949. extern "C" int pthread_attr_destroy(void *attr);
  950. static void *MsanThreadStartFunc(void *arg) {
  951. MsanThread *t = (MsanThread *)arg;
  952. SetCurrentThread(t);
  953. t->Init();
  954. SetSigProcMask(&t->starting_sigset_, nullptr);
  955. return t->ThreadStart();
  956. }
  957. INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
  958. void * param) {
  959. ENSURE_MSAN_INITED(); // for GetTlsSize()
  960. __sanitizer_pthread_attr_t myattr;
  961. if (!attr) {
  962. pthread_attr_init(&myattr);
  963. attr = &myattr;
  964. }
  965. AdjustStackSize(attr);
  966. MsanThread *t = MsanThread::Create(callback, param);
  967. ScopedBlockSignals block(&t->starting_sigset_);
  968. int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t);
  969. if (attr == &myattr)
  970. pthread_attr_destroy(&myattr);
  971. if (!res) {
  972. __msan_unpoison(th, __sanitizer::pthread_t_sz);
  973. }
  974. return res;
  975. }
  976. INTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,
  977. void (*dtor)(void *value)) {
  978. if (msan_init_is_running) return REAL(pthread_key_create)(key, dtor);
  979. ENSURE_MSAN_INITED();
  980. int res = REAL(pthread_key_create)(key, dtor);
  981. if (!res && key)
  982. __msan_unpoison(key, sizeof(*key));
  983. return res;
  984. }
  985. #if SANITIZER_NETBSD
  986. INTERCEPTOR(int, __libc_thr_keycreate, __sanitizer_pthread_key_t *m,
  987. void (*dtor)(void *value))
  988. ALIAS(WRAPPER_NAME(pthread_key_create));
  989. #endif
  990. INTERCEPTOR(int, pthread_join, void *th, void **retval) {
  991. ENSURE_MSAN_INITED();
  992. int res = REAL(pthread_join)(th, retval);
  993. if (!res && retval)
  994. __msan_unpoison(retval, sizeof(*retval));
  995. return res;
  996. }
  997. DEFINE_REAL_PTHREAD_FUNCTIONS
  998. extern char *tzname[2];
  999. INTERCEPTOR(void, tzset, int fake) {
  1000. ENSURE_MSAN_INITED();
  1001. InterceptorScope interceptor_scope;
  1002. REAL(tzset)(fake);
  1003. if (tzname[0])
  1004. __msan_unpoison(tzname[0], internal_strlen(tzname[0]) + 1);
  1005. if (tzname[1])
  1006. __msan_unpoison(tzname[1], internal_strlen(tzname[1]) + 1);
  1007. return;
  1008. }
  1009. struct MSanAtExitRecord {
  1010. void (*func)(void *arg);
  1011. void *arg;
  1012. };
  1013. struct InterceptorContext {
  1014. Mutex atexit_mu;
  1015. Vector<struct MSanAtExitRecord *> AtExitStack;
  1016. InterceptorContext()
  1017. : AtExitStack() {
  1018. }
  1019. };
  1020. static ALIGNED(64) char interceptor_placeholder[sizeof(InterceptorContext)];
  1021. InterceptorContext *interceptor_ctx() {
  1022. return reinterpret_cast<InterceptorContext*>(&interceptor_placeholder[0]);
  1023. }
  1024. void MSanAtExitWrapper() {
  1025. MSanAtExitRecord *r;
  1026. {
  1027. Lock l(&interceptor_ctx()->atexit_mu);
  1028. uptr element = interceptor_ctx()->AtExitStack.Size() - 1;
  1029. r = interceptor_ctx()->AtExitStack[element];
  1030. interceptor_ctx()->AtExitStack.PopBack();
  1031. }
  1032. UnpoisonParam(1);
  1033. ((void(*)())r->func)();
  1034. InternalFree(r);
  1035. }
  1036. void MSanCxaAtExitWrapper(void *arg) {
  1037. UnpoisonParam(1);
  1038. MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
  1039. // libc before 2.27 had race which caused occasional double handler execution
  1040. // https://sourceware.org/ml/libc-alpha/2017-08/msg01204.html
  1041. if (!r->func)
  1042. return;
  1043. r->func(r->arg);
  1044. r->func = nullptr;
  1045. }
  1046. static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso);
  1047. // Unpoison argument shadow for C++ module destructors.
  1048. INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
  1049. void *dso_handle) {
  1050. if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle);
  1051. return setup_at_exit_wrapper((void(*)())func, arg, dso_handle);
  1052. }
  1053. // Unpoison argument shadow for C++ module destructors.
  1054. INTERCEPTOR(int, atexit, void (*func)()) {
  1055. // Avoid calling real atexit as it is unreachable on at least on Linux.
  1056. if (msan_init_is_running)
  1057. return REAL(__cxa_atexit)((void (*)(void *a))func, 0, 0);
  1058. return setup_at_exit_wrapper((void(*)())func, 0, 0);
  1059. }
  1060. static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso) {
  1061. ENSURE_MSAN_INITED();
  1062. MSanAtExitRecord *r =
  1063. (MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));
  1064. r->func = (void(*)(void *a))f;
  1065. r->arg = arg;
  1066. int res;
  1067. if (!dso) {
  1068. // NetBSD does not preserve the 2nd argument if dso is equal to 0
  1069. // Store ctx in a local stack-like structure
  1070. Lock l(&interceptor_ctx()->atexit_mu);
  1071. res = REAL(__cxa_atexit)((void (*)(void *a))MSanAtExitWrapper, 0, 0);
  1072. if (!res) {
  1073. interceptor_ctx()->AtExitStack.PushBack(r);
  1074. }
  1075. } else {
  1076. res = REAL(__cxa_atexit)(MSanCxaAtExitWrapper, r, dso);
  1077. }
  1078. return res;
  1079. }
  1080. static void BeforeFork() {
  1081. StackDepotLockAll();
  1082. ChainedOriginDepotLockAll();
  1083. }
  1084. static void AfterFork() {
  1085. ChainedOriginDepotUnlockAll();
  1086. StackDepotUnlockAll();
  1087. }
  1088. INTERCEPTOR(int, fork, void) {
  1089. ENSURE_MSAN_INITED();
  1090. BeforeFork();
  1091. int pid = REAL(fork)();
  1092. AfterFork();
  1093. return pid;
  1094. }
  1095. // NetBSD ships with openpty(3) in -lutil, that needs to be prebuilt explicitly
  1096. // with MSan.
  1097. #if SANITIZER_LINUX
  1098. INTERCEPTOR(int, openpty, int *aparent, int *aworker, char *name,
  1099. const void *termp, const void *winp) {
  1100. ENSURE_MSAN_INITED();
  1101. InterceptorScope interceptor_scope;
  1102. int res = REAL(openpty)(aparent, aworker, name, termp, winp);
  1103. if (!res) {
  1104. __msan_unpoison(aparent, sizeof(*aparent));
  1105. __msan_unpoison(aworker, sizeof(*aworker));
  1106. }
  1107. return res;
  1108. }
  1109. #define MSAN_MAYBE_INTERCEPT_OPENPTY INTERCEPT_FUNCTION(openpty)
  1110. #else
  1111. #define MSAN_MAYBE_INTERCEPT_OPENPTY
  1112. #endif
  1113. // NetBSD ships with forkpty(3) in -lutil, that needs to be prebuilt explicitly
  1114. // with MSan.
  1115. #if SANITIZER_LINUX
  1116. INTERCEPTOR(int, forkpty, int *aparent, char *name, const void *termp,
  1117. const void *winp) {
  1118. ENSURE_MSAN_INITED();
  1119. InterceptorScope interceptor_scope;
  1120. int res = REAL(forkpty)(aparent, name, termp, winp);
  1121. if (res != -1)
  1122. __msan_unpoison(aparent, sizeof(*aparent));
  1123. return res;
  1124. }
  1125. #define MSAN_MAYBE_INTERCEPT_FORKPTY INTERCEPT_FUNCTION(forkpty)
  1126. #else
  1127. #define MSAN_MAYBE_INTERCEPT_FORKPTY
  1128. #endif
  1129. struct MSanInterceptorContext {
  1130. bool in_interceptor_scope;
  1131. };
  1132. namespace __msan {
  1133. int OnExit() {
  1134. // FIXME: ask frontend whether we need to return failure.
  1135. return 0;
  1136. }
  1137. } // namespace __msan
  1138. // A version of CHECK_UNPOISONED using a saved scope value. Used in common
  1139. // interceptors.
  1140. #define CHECK_UNPOISONED_CTX(ctx, x, n) \
  1141. do { \
  1142. if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \
  1143. CHECK_UNPOISONED_0(x, n); \
  1144. } while (0)
  1145. #define MSAN_INTERCEPT_FUNC(name) \
  1146. do { \
  1147. if (!INTERCEPT_FUNCTION(name)) \
  1148. VReport(1, "MemorySanitizer: failed to intercept '%s'\n", #name); \
  1149. } while (0)
  1150. #define MSAN_INTERCEPT_FUNC_VER(name, ver) \
  1151. do { \
  1152. if (!INTERCEPT_FUNCTION_VER(name, ver)) \
  1153. VReport(1, "MemorySanitizer: failed to intercept '%s@@%s'\n", #name, \
  1154. ver); \
  1155. } while (0)
  1156. #define MSAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver) \
  1157. do { \
  1158. if (!INTERCEPT_FUNCTION_VER(name, ver) && !INTERCEPT_FUNCTION(name)) \
  1159. VReport(1, "MemorySanitizer: failed to intercept '%s@@%s' or '%s'\n", \
  1160. #name, ver, #name); \
  1161. } while (0)
  1162. #define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)
  1163. #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
  1164. MSAN_INTERCEPT_FUNC_VER(name, ver)
  1165. #define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver) \
  1166. MSAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver)
  1167. #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) \
  1168. UnpoisonParam(count)
  1169. #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
  1170. __msan_unpoison(ptr, size)
  1171. #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
  1172. CHECK_UNPOISONED_CTX(ctx, ptr, size)
  1173. #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \
  1174. __msan_unpoison(ptr, size)
  1175. #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
  1176. if (msan_init_is_running) \
  1177. return REAL(func)(__VA_ARGS__); \
  1178. ENSURE_MSAN_INITED(); \
  1179. MSanInterceptorContext msan_ctx = {IsInInterceptorScope()}; \
  1180. ctx = (void *)&msan_ctx; \
  1181. (void)ctx; \
  1182. InterceptorScope interceptor_scope; \
  1183. __msan_unpoison(__errno_location(), sizeof(int));
  1184. #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
  1185. do { \
  1186. } while (false)
  1187. #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
  1188. do { \
  1189. } while (false)
  1190. #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
  1191. do { \
  1192. } while (false)
  1193. #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
  1194. do { \
  1195. } while (false)
  1196. #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
  1197. do { \
  1198. } while (false) // FIXME
  1199. #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
  1200. do { \
  1201. } while (false) // FIXME
  1202. #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
  1203. #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
  1204. #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
  1205. do { \
  1206. link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE((handle)); \
  1207. if (filename && map) \
  1208. ForEachMappedRegion(map, __msan_unpoison); \
  1209. } while (false)
  1210. #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!msan_inited)
  1211. #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \
  1212. if (MsanThread *t = GetCurrentThread()) { \
  1213. *begin = t->tls_begin(); \
  1214. *end = t->tls_end(); \
  1215. } else { \
  1216. *begin = *end = 0; \
  1217. }
  1218. #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
  1219. { \
  1220. (void)ctx; \
  1221. return __msan_memset(block, c, size); \
  1222. }
  1223. #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
  1224. { \
  1225. (void)ctx; \
  1226. return __msan_memmove(to, from, size); \
  1227. }
  1228. #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
  1229. { \
  1230. (void)ctx; \
  1231. return __msan_memcpy(to, from, size); \
  1232. }
  1233. #define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) \
  1234. do { \
  1235. GET_STORE_STACK_TRACE; \
  1236. CopyShadowAndOrigin(to, from, size, &stack); \
  1237. __msan_unpoison(to + size, 1); \
  1238. } while (false)
  1239. #define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \
  1240. offset) \
  1241. do { \
  1242. return mmap_interceptor(REAL(mmap), addr, sz, prot, flags, fd, off); \
  1243. } while (false)
  1244. #include "sanitizer_common/sanitizer_platform_interceptors.h"
  1245. #include "sanitizer_common/sanitizer_common_interceptors.inc"
  1246. static uptr signal_impl(int signo, uptr cb);
  1247. static int sigaction_impl(int signo, const __sanitizer_sigaction *act,
  1248. __sanitizer_sigaction *oldact);
  1249. #define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signo, act, oldact) \
  1250. { return sigaction_impl(signo, act, oldact); }
  1251. #define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signo, handler) \
  1252. { \
  1253. handler = signal_impl(signo, handler); \
  1254. InterceptorScope interceptor_scope; \
  1255. return REAL(func)(signo, handler); \
  1256. }
  1257. #include "sanitizer_common/sanitizer_signal_interceptors.inc"
  1258. static int sigaction_impl(int signo, const __sanitizer_sigaction *act,
  1259. __sanitizer_sigaction *oldact) {
  1260. ENSURE_MSAN_INITED();
  1261. if (signo <= 0 || signo >= kMaxSignals) {
  1262. errno = errno_EINVAL;
  1263. return -1;
  1264. }
  1265. if (act) read_sigaction(act);
  1266. int res;
  1267. if (flags()->wrap_signals) {
  1268. SpinMutexLock lock(&sigactions_mu);
  1269. uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);
  1270. __sanitizer_sigaction new_act;
  1271. __sanitizer_sigaction *pnew_act = act ? &new_act : nullptr;
  1272. if (act) {
  1273. REAL(memcpy)(pnew_act, act, sizeof(__sanitizer_sigaction));
  1274. uptr cb = (uptr)pnew_act->sigaction;
  1275. uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)
  1276. ? (uptr)SignalAction
  1277. : (uptr)SignalHandler;
  1278. if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
  1279. atomic_store(&sigactions[signo], cb, memory_order_relaxed);
  1280. pnew_act->sigaction = (decltype(pnew_act->sigaction))new_cb;
  1281. }
  1282. }
  1283. res = REAL(SIGACTION_SYMNAME)(signo, pnew_act, oldact);
  1284. if (res == 0 && oldact) {
  1285. uptr cb = (uptr)oldact->sigaction;
  1286. if (cb == (uptr)SignalAction || cb == (uptr)SignalHandler) {
  1287. oldact->sigaction = (decltype(oldact->sigaction))old_cb;
  1288. }
  1289. }
  1290. } else {
  1291. res = REAL(SIGACTION_SYMNAME)(signo, act, oldact);
  1292. }
  1293. if (res == 0 && oldact) {
  1294. __msan_unpoison(oldact, sizeof(__sanitizer_sigaction));
  1295. }
  1296. return res;
  1297. }
  1298. static uptr signal_impl(int signo, uptr cb) {
  1299. ENSURE_MSAN_INITED();
  1300. if (signo <= 0 || signo >= kMaxSignals) {
  1301. errno = errno_EINVAL;
  1302. return -1;
  1303. }
  1304. if (flags()->wrap_signals) {
  1305. SpinMutexLock lock(&sigactions_mu);
  1306. if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
  1307. atomic_store(&sigactions[signo], cb, memory_order_relaxed);
  1308. cb = (uptr)&SignalHandler;
  1309. }
  1310. }
  1311. return cb;
  1312. }
  1313. #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
  1314. #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \
  1315. do { \
  1316. } while (false)
  1317. #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
  1318. do { \
  1319. } while (false)
  1320. #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
  1321. #include "sanitizer_common/sanitizer_common_syscalls.inc"
  1322. #include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
  1323. INTERCEPTOR(const char *, strsignal, int sig) {
  1324. void *ctx;
  1325. COMMON_INTERCEPTOR_ENTER(ctx, strsignal, sig);
  1326. const char *res = REAL(strsignal)(sig);
  1327. if (res)
  1328. __msan_unpoison(res, internal_strlen(res) + 1);
  1329. return res;
  1330. }
  1331. struct dlinfo {
  1332. char *dli_fname;
  1333. void *dli_fbase;
  1334. char *dli_sname;
  1335. void *dli_saddr;
  1336. };
  1337. INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
  1338. void *ctx;
  1339. COMMON_INTERCEPTOR_ENTER(ctx, dladdr, addr, info);
  1340. int res = REAL(dladdr)(addr, info);
  1341. if (res != 0) {
  1342. __msan_unpoison(info, sizeof(*info));
  1343. if (info->dli_fname)
  1344. __msan_unpoison(info->dli_fname, internal_strlen(info->dli_fname) + 1);
  1345. if (info->dli_sname)
  1346. __msan_unpoison(info->dli_sname, internal_strlen(info->dli_sname) + 1);
  1347. }
  1348. return res;
  1349. }
  1350. INTERCEPTOR(char *, dlerror, int fake) {
  1351. void *ctx;
  1352. COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake);
  1353. char *res = REAL(dlerror)(fake);
  1354. if (res)
  1355. __msan_unpoison(res, internal_strlen(res) + 1);
  1356. return res;
  1357. }
  1358. typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
  1359. void *data);
  1360. struct dl_iterate_phdr_data {
  1361. dl_iterate_phdr_cb callback;
  1362. void *data;
  1363. };
  1364. static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
  1365. void *data) {
  1366. if (info) {
  1367. __msan_unpoison(info, size);
  1368. if (info->dlpi_phdr && info->dlpi_phnum)
  1369. __msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);
  1370. if (info->dlpi_name)
  1371. __msan_unpoison(info->dlpi_name, internal_strlen(info->dlpi_name) + 1);
  1372. }
  1373. dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
  1374. UnpoisonParam(3);
  1375. return cbdata->callback(info, size, cbdata->data);
  1376. }
  1377. INTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {
  1378. ENSURE_MSAN_INITED();
  1379. void *p = REAL(shmat)(shmid, shmaddr, shmflg);
  1380. if (p != (void *)-1) {
  1381. __sanitizer_shmid_ds ds;
  1382. int res = REAL(shmctl)(shmid, shmctl_ipc_stat, &ds);
  1383. if (!res) {
  1384. __msan_unpoison(p, ds.shm_segsz);
  1385. }
  1386. }
  1387. return p;
  1388. }
  1389. INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
  1390. void *ctx;
  1391. COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data);
  1392. dl_iterate_phdr_data cbdata;
  1393. cbdata.callback = callback;
  1394. cbdata.data = data;
  1395. int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
  1396. return res;
  1397. }
  1398. // wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
  1399. INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
  1400. ENSURE_MSAN_INITED();
  1401. wchar_t *res = REAL(wcschr)(s, wc, ps);
  1402. return res;
  1403. }
  1404. // wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
  1405. INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
  1406. ENSURE_MSAN_INITED();
  1407. GET_STORE_STACK_TRACE;
  1408. wchar_t *res = REAL(wcscpy)(dest, src);
  1409. CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (internal_wcslen(src) + 1),
  1410. &stack);
  1411. return res;
  1412. }
  1413. INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
  1414. ENSURE_MSAN_INITED();
  1415. GET_STORE_STACK_TRACE;
  1416. SIZE_T copy_size = internal_wcsnlen(src, n);
  1417. if (copy_size < n) copy_size++; // trailing \0
  1418. wchar_t *res = REAL(wcsncpy)(dest, src, n);
  1419. CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack);
  1420. __msan_unpoison(dest + copy_size, (n - copy_size) * sizeof(wchar_t));
  1421. return res;
  1422. }
  1423. // These interface functions reside here so that they can use
  1424. // REAL(memset), etc.
  1425. void __msan_unpoison(const void *a, uptr size) {
  1426. if (!MEM_IS_APP(a)) return;
  1427. SetShadow(a, size, 0);
  1428. }
  1429. void __msan_poison(const void *a, uptr size) {
  1430. if (!MEM_IS_APP(a)) return;
  1431. SetShadow(a, size, __msan::flags()->poison_heap_with_zeroes ? 0 : -1);
  1432. }
  1433. void __msan_poison_stack(void *a, uptr size) {
  1434. if (!MEM_IS_APP(a)) return;
  1435. SetShadow(a, size, __msan::flags()->poison_stack_with_zeroes ? 0 : -1);
  1436. }
  1437. void __msan_unpoison_param(uptr n) { UnpoisonParam(n); }
  1438. void __msan_clear_and_unpoison(void *a, uptr size) {
  1439. REAL(memset)(a, 0, size);
  1440. SetShadow(a, size, 0);
  1441. }
  1442. void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
  1443. if (!msan_inited) return internal_memcpy(dest, src, n);
  1444. if (msan_init_is_running || __msan::IsInSymbolizerOrUnwider())
  1445. return REAL(memcpy)(dest, src, n);
  1446. ENSURE_MSAN_INITED();
  1447. GET_STORE_STACK_TRACE;
  1448. void *res = REAL(memcpy)(dest, src, n);
  1449. CopyShadowAndOrigin(dest, src, n, &stack);
  1450. return res;
  1451. }
  1452. void *__msan_memset(void *s, int c, SIZE_T n) {
  1453. if (!msan_inited) return internal_memset(s, c, n);
  1454. if (msan_init_is_running) return REAL(memset)(s, c, n);
  1455. ENSURE_MSAN_INITED();
  1456. void *res = REAL(memset)(s, c, n);
  1457. __msan_unpoison(s, n);
  1458. return res;
  1459. }
  1460. void *__msan_memmove(void *dest, const void *src, SIZE_T n) {
  1461. if (!msan_inited) return internal_memmove(dest, src, n);
  1462. if (msan_init_is_running) return REAL(memmove)(dest, src, n);
  1463. ENSURE_MSAN_INITED();
  1464. GET_STORE_STACK_TRACE;
  1465. void *res = REAL(memmove)(dest, src, n);
  1466. MoveShadowAndOrigin(dest, src, n, &stack);
  1467. return res;
  1468. }
  1469. void __msan_unpoison_string(const char* s) {
  1470. if (!MEM_IS_APP(s)) return;
  1471. __msan_unpoison(s, internal_strlen(s) + 1);
  1472. }
  1473. namespace __msan {
  1474. void InitializeInterceptors() {
  1475. static int inited = 0;
  1476. CHECK_EQ(inited, 0);
  1477. new(interceptor_ctx()) InterceptorContext();
  1478. InitializeCommonInterceptors();
  1479. InitializeSignalInterceptors();
  1480. INTERCEPT_FUNCTION(posix_memalign);
  1481. MSAN_MAYBE_INTERCEPT_MEMALIGN;
  1482. MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
  1483. INTERCEPT_FUNCTION(valloc);
  1484. MSAN_MAYBE_INTERCEPT_PVALLOC;
  1485. INTERCEPT_FUNCTION(malloc);
  1486. INTERCEPT_FUNCTION(calloc);
  1487. INTERCEPT_FUNCTION(realloc);
  1488. INTERCEPT_FUNCTION(reallocarray);
  1489. INTERCEPT_FUNCTION(free);
  1490. MSAN_MAYBE_INTERCEPT_CFREE;
  1491. MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE;
  1492. MSAN_MAYBE_INTERCEPT_MALLINFO;
  1493. MSAN_MAYBE_INTERCEPT_MALLOPT;
  1494. MSAN_MAYBE_INTERCEPT_MALLOC_STATS;
  1495. INTERCEPT_FUNCTION(fread);
  1496. MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED;
  1497. INTERCEPT_FUNCTION(memccpy);
  1498. MSAN_MAYBE_INTERCEPT_MEMPCPY;
  1499. INTERCEPT_FUNCTION(bcopy);
  1500. INTERCEPT_FUNCTION(wmemset);
  1501. INTERCEPT_FUNCTION(wmemcpy);
  1502. MSAN_MAYBE_INTERCEPT_WMEMPCPY;
  1503. INTERCEPT_FUNCTION(wmemmove);
  1504. INTERCEPT_FUNCTION(strcpy);
  1505. MSAN_MAYBE_INTERCEPT_STPCPY;
  1506. MSAN_MAYBE_INTERCEPT_STPNCPY;
  1507. INTERCEPT_FUNCTION(strdup);
  1508. MSAN_MAYBE_INTERCEPT___STRDUP;
  1509. INTERCEPT_FUNCTION(strncpy);
  1510. MSAN_MAYBE_INTERCEPT_GCVT;
  1511. INTERCEPT_FUNCTION(strcat);
  1512. INTERCEPT_FUNCTION(strncat);
  1513. INTERCEPT_STRTO(strtod);
  1514. INTERCEPT_STRTO(strtof);
  1515. INTERCEPT_STRTO(strtold);
  1516. INTERCEPT_STRTO(strtol);
  1517. INTERCEPT_STRTO(strtoul);
  1518. INTERCEPT_STRTO(strtoll);
  1519. INTERCEPT_STRTO(strtoull);
  1520. INTERCEPT_STRTO(strtouq);
  1521. INTERCEPT_STRTO(wcstod);
  1522. INTERCEPT_STRTO(wcstof);
  1523. INTERCEPT_STRTO(wcstold);
  1524. INTERCEPT_STRTO(wcstol);
  1525. INTERCEPT_STRTO(wcstoul);
  1526. INTERCEPT_STRTO(wcstoll);
  1527. INTERCEPT_STRTO(wcstoull);
  1528. #ifdef SANITIZER_NLDBL_VERSION
  1529. INTERCEPT_FUNCTION_VER(vswprintf, SANITIZER_NLDBL_VERSION);
  1530. INTERCEPT_FUNCTION_VER(swprintf, SANITIZER_NLDBL_VERSION);
  1531. #else
  1532. INTERCEPT_FUNCTION(vswprintf);
  1533. INTERCEPT_FUNCTION(swprintf);
  1534. #endif
  1535. INTERCEPT_FUNCTION(strftime);
  1536. INTERCEPT_FUNCTION(strftime_l);
  1537. MSAN_MAYBE_INTERCEPT___STRFTIME_L;
  1538. INTERCEPT_FUNCTION(wcsftime);
  1539. INTERCEPT_FUNCTION(wcsftime_l);
  1540. MSAN_MAYBE_INTERCEPT___WCSFTIME_L;
  1541. INTERCEPT_FUNCTION(mbtowc);
  1542. INTERCEPT_FUNCTION(mbrtowc);
  1543. INTERCEPT_FUNCTION(wcslen);
  1544. INTERCEPT_FUNCTION(wcsnlen);
  1545. INTERCEPT_FUNCTION(wcschr);
  1546. INTERCEPT_FUNCTION(wcscpy);
  1547. INTERCEPT_FUNCTION(wcsncpy);
  1548. INTERCEPT_FUNCTION(wcscmp);
  1549. INTERCEPT_FUNCTION(getenv);
  1550. INTERCEPT_FUNCTION(setenv);
  1551. INTERCEPT_FUNCTION(putenv);
  1552. INTERCEPT_FUNCTION(gettimeofday);
  1553. MSAN_MAYBE_INTERCEPT_FCVT;
  1554. MSAN_MAYBE_INTERCEPT_FSTAT;
  1555. MSAN_MAYBE_INTERCEPT_FSTAT64;
  1556. MSAN_MAYBE_INTERCEPT___FXSTAT;
  1557. MSAN_MAYBE_INTERCEPT_FSTATAT;
  1558. MSAN_MAYBE_INTERCEPT_FSTATAT64;
  1559. MSAN_MAYBE_INTERCEPT___FXSTATAT;
  1560. MSAN_MAYBE_INTERCEPT___FXSTAT64;
  1561. MSAN_MAYBE_INTERCEPT___FXSTATAT64;
  1562. INTERCEPT_FUNCTION(pipe);
  1563. INTERCEPT_FUNCTION(pipe2);
  1564. INTERCEPT_FUNCTION(socketpair);
  1565. MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED;
  1566. INTERCEPT_FUNCTION(getrlimit);
  1567. MSAN_MAYBE_INTERCEPT___GETRLIMIT;
  1568. MSAN_MAYBE_INTERCEPT_GETRLIMIT64;
  1569. MSAN_MAYBE_INTERCEPT_PRLIMIT;
  1570. MSAN_MAYBE_INTERCEPT_PRLIMIT64;
  1571. INTERCEPT_FUNCTION(gethostname);
  1572. MSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
  1573. MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;
  1574. INTERCEPT_FUNCTION(strsignal);
  1575. INTERCEPT_FUNCTION(dladdr);
  1576. INTERCEPT_FUNCTION(dlerror);
  1577. INTERCEPT_FUNCTION(dl_iterate_phdr);
  1578. INTERCEPT_FUNCTION(getrusage);
  1579. #if defined(__mips__)
  1580. INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2");
  1581. #else
  1582. INTERCEPT_FUNCTION(pthread_create);
  1583. #endif
  1584. INTERCEPT_FUNCTION(pthread_join);
  1585. INTERCEPT_FUNCTION(pthread_key_create);
  1586. #if SANITIZER_NETBSD
  1587. INTERCEPT_FUNCTION(__libc_thr_keycreate);
  1588. #endif
  1589. INTERCEPT_FUNCTION(pthread_join);
  1590. INTERCEPT_FUNCTION(tzset);
  1591. INTERCEPT_FUNCTION(atexit);
  1592. INTERCEPT_FUNCTION(__cxa_atexit);
  1593. INTERCEPT_FUNCTION(shmat);
  1594. INTERCEPT_FUNCTION(fork);
  1595. MSAN_MAYBE_INTERCEPT_OPENPTY;
  1596. MSAN_MAYBE_INTERCEPT_FORKPTY;
  1597. inited = 1;
  1598. }
  1599. } // namespace __msan