asan_interceptors.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. //===-- asan_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 AddressSanitizer, an address sanity checker.
  10. //
  11. // Intercept various libc functions.
  12. //===----------------------------------------------------------------------===//
  13. #include "asan_interceptors.h"
  14. #include "asan_allocator.h"
  15. #include "asan_internal.h"
  16. #include "asan_mapping.h"
  17. #include "asan_poisoning.h"
  18. #include "asan_report.h"
  19. #include "asan_stack.h"
  20. #include "asan_stats.h"
  21. #include "asan_suppressions.h"
  22. #include "asan_thread.h"
  23. #include "lsan/lsan_common.h"
  24. #include "sanitizer_common/sanitizer_errno.h"
  25. #include "sanitizer_common/sanitizer_internal_defs.h"
  26. #include "sanitizer_common/sanitizer_libc.h"
  27. // There is no general interception at all on Fuchsia.
  28. // Only the functions in asan_interceptors_memintrinsics.cpp are
  29. // really defined to replace libc functions.
  30. #if !SANITIZER_FUCHSIA
  31. # if SANITIZER_POSIX
  32. # include "sanitizer_common/sanitizer_posix.h"
  33. # endif
  34. # if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION || \
  35. ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION
  36. # include <unwind.h>
  37. # endif
  38. # if defined(__i386) && SANITIZER_LINUX
  39. # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1"
  40. # elif defined(__mips__) && SANITIZER_LINUX
  41. # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2"
  42. # endif
  43. namespace __asan {
  44. #define ASAN_READ_STRING_OF_LEN(ctx, s, len, n) \
  45. ASAN_READ_RANGE((ctx), (s), \
  46. common_flags()->strict_string_checks ? (len) + 1 : (n))
  47. # define ASAN_READ_STRING(ctx, s, n) \
  48. ASAN_READ_STRING_OF_LEN((ctx), (s), internal_strlen(s), (n))
  49. static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
  50. #if SANITIZER_INTERCEPT_STRNLEN
  51. if (REAL(strnlen)) {
  52. return REAL(strnlen)(s, maxlen);
  53. }
  54. #endif
  55. return internal_strnlen(s, maxlen);
  56. }
  57. void SetThreadName(const char *name) {
  58. AsanThread *t = GetCurrentThread();
  59. if (t)
  60. asanThreadRegistry().SetThreadName(t->tid(), name);
  61. }
  62. int OnExit() {
  63. if (CAN_SANITIZE_LEAKS && common_flags()->detect_leaks &&
  64. __lsan::HasReportedLeaks()) {
  65. return common_flags()->exitcode;
  66. }
  67. // FIXME: ask frontend whether we need to return failure.
  68. return 0;
  69. }
  70. } // namespace __asan
  71. // ---------------------- Wrappers ---------------- {{{1
  72. using namespace __asan;
  73. DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
  74. DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
  75. #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
  76. ASAN_INTERCEPT_FUNC_VER(name, ver)
  77. #define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver) \
  78. ASAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver)
  79. #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
  80. ASAN_WRITE_RANGE(ctx, ptr, size)
  81. #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
  82. ASAN_READ_RANGE(ctx, ptr, size)
  83. # define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
  84. ASAN_INTERCEPTOR_ENTER(ctx, func); \
  85. do { \
  86. if constexpr (SANITIZER_APPLE) { \
  87. if (UNLIKELY(!AsanInited())) \
  88. return REAL(func)(__VA_ARGS__); \
  89. } else { \
  90. if (!TryAsanInitFromRtl()) \
  91. return REAL(func)(__VA_ARGS__); \
  92. } \
  93. } while (false)
  94. #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
  95. do { \
  96. } while (false)
  97. #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
  98. do { \
  99. } while (false)
  100. #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
  101. do { \
  102. } while (false)
  103. #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
  104. do { \
  105. } while (false)
  106. #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
  107. // Should be asanThreadRegistry().SetThreadNameByUserId(thread, name)
  108. // But asan does not remember UserId's for threads (pthread_t);
  109. // and remembers all ever existed threads, so the linear search by UserId
  110. // can be slow.
  111. #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
  112. do { \
  113. } while (false)
  114. #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
  115. // Strict init-order checking is dlopen-hostile:
  116. // https://github.com/google/sanitizers/issues/178
  117. # define COMMON_INTERCEPTOR_DLOPEN(filename, flag) \
  118. ({ \
  119. if (flags()->strict_init_order) \
  120. StopInitOrderChecking(); \
  121. CheckNoDeepBind(filename, flag); \
  122. REAL(dlopen)(filename, flag); \
  123. })
  124. # define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
  125. # define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)
  126. # define COMMON_INTERCEPTOR_LIBRARY_UNLOADED()
  127. # define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!AsanInited())
  128. # define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \
  129. if (AsanThread *t = GetCurrentThread()) { \
  130. *begin = t->tls_begin(); \
  131. *end = t->tls_end(); \
  132. } else { \
  133. *begin = *end = 0; \
  134. }
  135. template <class Mmap>
  136. static void* mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
  137. int prot, int flags, int fd, OFF64_T offset) {
  138. void *res = real_mmap(addr, length, prot, flags, fd, offset);
  139. if (length && res != (void *)-1) {
  140. const uptr beg = reinterpret_cast<uptr>(res);
  141. DCHECK(IsAligned(beg, GetPageSize()));
  142. SIZE_T rounded_length = RoundUpTo(length, GetPageSize());
  143. // Only unpoison shadow if it's an ASAN managed address.
  144. if (AddrIsInMem(beg) && AddrIsInMem(beg + rounded_length - 1))
  145. PoisonShadow(beg, RoundUpTo(length, GetPageSize()), 0);
  146. }
  147. return res;
  148. }
  149. template <class Munmap>
  150. static int munmap_interceptor(Munmap real_munmap, void *addr, SIZE_T length) {
  151. // We should not tag if munmap fail, but it's to late to tag after
  152. // real_munmap, as the pages could be mmaped by another thread.
  153. const uptr beg = reinterpret_cast<uptr>(addr);
  154. if (length && IsAligned(beg, GetPageSize())) {
  155. SIZE_T rounded_length = RoundUpTo(length, GetPageSize());
  156. // Protect from unmapping the shadow.
  157. if (AddrIsInMem(beg) && AddrIsInMem(beg + rounded_length - 1))
  158. PoisonShadow(beg, rounded_length, 0);
  159. }
  160. return real_munmap(addr, length);
  161. }
  162. # define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, \
  163. fd, offset) \
  164. do { \
  165. (void)(ctx); \
  166. return mmap_interceptor(REAL(mmap), addr, sz, prot, flags, fd, off); \
  167. } while (false)
  168. # define COMMON_INTERCEPTOR_MUNMAP_IMPL(ctx, addr, length) \
  169. do { \
  170. (void)(ctx); \
  171. return munmap_interceptor(REAL(munmap), addr, sz); \
  172. } while (false)
  173. #if CAN_SANITIZE_LEAKS
  174. #define COMMON_INTERCEPTOR_STRERROR() \
  175. __lsan::ScopedInterceptorDisabler disabler
  176. #endif
  177. # define SIGNAL_INTERCEPTOR_ENTER() \
  178. do { \
  179. AsanInitFromRtl(); \
  180. } while (false)
  181. # include "sanitizer_common/sanitizer_common_interceptors.inc"
  182. # include "sanitizer_common/sanitizer_signal_interceptors.inc"
  183. // Syscall interceptors don't have contexts, we don't support suppressions
  184. // for them.
  185. #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s)
  186. #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s)
  187. #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
  188. do { \
  189. (void)(p); \
  190. (void)(s); \
  191. } while (false)
  192. #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \
  193. do { \
  194. (void)(p); \
  195. (void)(s); \
  196. } while (false)
  197. #include "sanitizer_common/sanitizer_common_syscalls.inc"
  198. #include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
  199. #if ASAN_INTERCEPT_PTHREAD_CREATE
  200. static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
  201. AsanThread *t = (AsanThread *)arg;
  202. SetCurrentThread(t);
  203. auto self = GetThreadSelf();
  204. auto args = asanThreadArgRetval().GetArgs(self);
  205. t->ThreadStart(GetTid());
  206. # if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
  207. SANITIZER_SOLARIS
  208. __sanitizer_sigset_t sigset;
  209. t->GetStartData(sigset);
  210. SetSigProcMask(&sigset, nullptr);
  211. # endif
  212. thread_return_t retval = (*args.routine)(args.arg_retval);
  213. asanThreadArgRetval().Finish(self, retval);
  214. return retval;
  215. }
  216. INTERCEPTOR(int, pthread_create, void *thread, void *attr,
  217. void *(*start_routine)(void *), void *arg) {
  218. EnsureMainThreadIDIsCorrect();
  219. // Strict init-order checking is thread-hostile.
  220. if (flags()->strict_init_order)
  221. StopInitOrderChecking();
  222. GET_STACK_TRACE_THREAD;
  223. bool detached = [attr]() {
  224. int d = 0;
  225. return attr && !REAL(pthread_attr_getdetachstate)(attr, &d) &&
  226. IsStateDetached(d);
  227. }();
  228. u32 current_tid = GetCurrentTidOrInvalid();
  229. __sanitizer_sigset_t sigset = {};
  230. # if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
  231. SANITIZER_SOLARIS
  232. ScopedBlockSignals block(&sigset);
  233. # endif
  234. AsanThread *t = AsanThread::Create(sigset, current_tid, &stack, detached);
  235. int result;
  236. {
  237. // Ignore all allocations made by pthread_create: thread stack/TLS may be
  238. // stored by pthread for future reuse even after thread destruction, and
  239. // the linked list it's stored in doesn't even hold valid pointers to the
  240. // objects, the latter are calculated by obscure pointer arithmetic.
  241. # if CAN_SANITIZE_LEAKS
  242. __lsan::ScopedInterceptorDisabler disabler;
  243. # endif
  244. asanThreadArgRetval().Create(detached, {start_routine, arg}, [&]() -> uptr {
  245. result = REAL(pthread_create)(thread, attr, asan_thread_start, t);
  246. return result ? 0 : *(uptr *)(thread);
  247. });
  248. }
  249. if (result != 0) {
  250. // If the thread didn't start delete the AsanThread to avoid leaking it.
  251. // Note AsanThreadContexts never get destroyed so the AsanThreadContext
  252. // that was just created for the AsanThread is wasted.
  253. t->Destroy();
  254. }
  255. return result;
  256. }
  257. INTERCEPTOR(int, pthread_join, void *thread, void **retval) {
  258. int result;
  259. asanThreadArgRetval().Join((uptr)thread, [&]() {
  260. result = REAL(pthread_join)(thread, retval);
  261. return !result;
  262. });
  263. return result;
  264. }
  265. INTERCEPTOR(int, pthread_detach, void *thread) {
  266. int result;
  267. asanThreadArgRetval().Detach((uptr)thread, [&]() {
  268. result = REAL(pthread_detach)(thread);
  269. return !result;
  270. });
  271. return result;
  272. }
  273. INTERCEPTOR(void, pthread_exit, void *retval) {
  274. asanThreadArgRetval().Finish(GetThreadSelf(), retval);
  275. REAL(pthread_exit)(retval);
  276. }
  277. # if ASAN_INTERCEPT_TRYJOIN
  278. INTERCEPTOR(int, pthread_tryjoin_np, void *thread, void **ret) {
  279. int result;
  280. asanThreadArgRetval().Join((uptr)thread, [&]() {
  281. result = REAL(pthread_tryjoin_np)(thread, ret);
  282. return !result;
  283. });
  284. return result;
  285. }
  286. # endif
  287. # if ASAN_INTERCEPT_TIMEDJOIN
  288. INTERCEPTOR(int, pthread_timedjoin_np, void *thread, void **ret,
  289. const struct timespec *abstime) {
  290. int result;
  291. asanThreadArgRetval().Join((uptr)thread, [&]() {
  292. result = REAL(pthread_timedjoin_np)(thread, ret, abstime);
  293. return !result;
  294. });
  295. return result;
  296. }
  297. # endif
  298. DEFINE_REAL_PTHREAD_FUNCTIONS
  299. #endif // ASAN_INTERCEPT_PTHREAD_CREATE
  300. #if ASAN_INTERCEPT_SWAPCONTEXT
  301. static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
  302. // Only clear if we know the stack. This should be true only for contexts
  303. // created with makecontext().
  304. if (!ssize)
  305. return;
  306. // Align to page size.
  307. uptr PageSize = GetPageSizeCached();
  308. uptr bottom = RoundDownTo(stack, PageSize);
  309. if (!AddrIsInMem(bottom))
  310. return;
  311. ssize += stack - bottom;
  312. ssize = RoundUpTo(ssize, PageSize);
  313. PoisonShadow(bottom, ssize, 0);
  314. }
  315. INTERCEPTOR(void, makecontext, struct ucontext_t *ucp, void (*func)(), int argc,
  316. ...) {
  317. va_list ap;
  318. uptr args[64];
  319. // We don't know a better way to forward ... into REAL function. We can
  320. // increase args size if neccecary.
  321. CHECK_LE(argc, ARRAY_SIZE(args));
  322. internal_memset(args, 0, sizeof(args));
  323. va_start(ap, argc);
  324. for (int i = 0; i < argc; ++i) args[i] = va_arg(ap, uptr);
  325. va_end(ap);
  326. # define ENUMERATE_ARRAY_4(start) \
  327. args[start], args[start + 1], args[start + 2], args[start + 3]
  328. # define ENUMERATE_ARRAY_16(start) \
  329. ENUMERATE_ARRAY_4(start), ENUMERATE_ARRAY_4(start + 4), \
  330. ENUMERATE_ARRAY_4(start + 8), ENUMERATE_ARRAY_4(start + 12)
  331. # define ENUMERATE_ARRAY_64() \
  332. ENUMERATE_ARRAY_16(0), ENUMERATE_ARRAY_16(16), ENUMERATE_ARRAY_16(32), \
  333. ENUMERATE_ARRAY_16(48)
  334. REAL(makecontext)
  335. ((struct ucontext_t *)ucp, func, argc, ENUMERATE_ARRAY_64());
  336. # undef ENUMERATE_ARRAY_4
  337. # undef ENUMERATE_ARRAY_16
  338. # undef ENUMERATE_ARRAY_64
  339. // Sign the stack so we can identify it for unpoisoning.
  340. SignContextStack(ucp);
  341. }
  342. INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
  343. struct ucontext_t *ucp) {
  344. static bool reported_warning = false;
  345. if (!reported_warning) {
  346. Report("WARNING: ASan doesn't fully support makecontext/swapcontext "
  347. "functions and may produce false positives in some cases!\n");
  348. reported_warning = true;
  349. }
  350. // Clear shadow memory for new context (it may share stack
  351. // with current context).
  352. uptr stack, ssize;
  353. ReadContextStack(ucp, &stack, &ssize);
  354. ClearShadowMemoryForContextStack(stack, ssize);
  355. # if __has_attribute(__indirect_return__) && \
  356. (defined(__x86_64__) || defined(__i386__))
  357. int (*real_swapcontext)(struct ucontext_t *, struct ucontext_t *)
  358. __attribute__((__indirect_return__)) = REAL(swapcontext);
  359. int res = real_swapcontext(oucp, ucp);
  360. # else
  361. int res = REAL(swapcontext)(oucp, ucp);
  362. # endif
  363. // swapcontext technically does not return, but program may swap context to
  364. // "oucp" later, that would look as if swapcontext() returned 0.
  365. // We need to clear shadow for ucp once again, as it may be in arbitrary
  366. // state.
  367. ClearShadowMemoryForContextStack(stack, ssize);
  368. return res;
  369. }
  370. #endif // ASAN_INTERCEPT_SWAPCONTEXT
  371. #if SANITIZER_NETBSD
  372. #define longjmp __longjmp14
  373. #define siglongjmp __siglongjmp14
  374. #endif
  375. INTERCEPTOR(void, longjmp, void *env, int val) {
  376. __asan_handle_no_return();
  377. REAL(longjmp)(env, val);
  378. }
  379. #if ASAN_INTERCEPT__LONGJMP
  380. INTERCEPTOR(void, _longjmp, void *env, int val) {
  381. __asan_handle_no_return();
  382. REAL(_longjmp)(env, val);
  383. }
  384. #endif
  385. #if ASAN_INTERCEPT___LONGJMP_CHK
  386. INTERCEPTOR(void, __longjmp_chk, void *env, int val) {
  387. __asan_handle_no_return();
  388. REAL(__longjmp_chk)(env, val);
  389. }
  390. #endif
  391. #if ASAN_INTERCEPT_SIGLONGJMP
  392. INTERCEPTOR(void, siglongjmp, void *env, int val) {
  393. __asan_handle_no_return();
  394. REAL(siglongjmp)(env, val);
  395. }
  396. #endif
  397. #if ASAN_INTERCEPT___CXA_THROW
  398. INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
  399. CHECK(REAL(__cxa_throw));
  400. __asan_handle_no_return();
  401. REAL(__cxa_throw)(a, b, c);
  402. }
  403. #endif
  404. #if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION
  405. INTERCEPTOR(void, __cxa_rethrow_primary_exception, void *a) {
  406. CHECK(REAL(__cxa_rethrow_primary_exception));
  407. __asan_handle_no_return();
  408. REAL(__cxa_rethrow_primary_exception)(a);
  409. }
  410. #endif
  411. #if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION
  412. INTERCEPTOR(_Unwind_Reason_Code, _Unwind_RaiseException,
  413. _Unwind_Exception *object) {
  414. CHECK(REAL(_Unwind_RaiseException));
  415. __asan_handle_no_return();
  416. return REAL(_Unwind_RaiseException)(object);
  417. }
  418. #endif
  419. #if ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION
  420. INTERCEPTOR(_Unwind_Reason_Code, _Unwind_SjLj_RaiseException,
  421. _Unwind_Exception *object) {
  422. CHECK(REAL(_Unwind_SjLj_RaiseException));
  423. __asan_handle_no_return();
  424. return REAL(_Unwind_SjLj_RaiseException)(object);
  425. }
  426. #endif
  427. #if ASAN_INTERCEPT_INDEX
  428. # if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
  429. INTERCEPTOR(char*, index, const char *string, int c)
  430. ALIAS(WRAP(strchr));
  431. # else
  432. # if SANITIZER_APPLE
  433. DECLARE_REAL(char*, index, const char *string, int c)
  434. OVERRIDE_FUNCTION(index, strchr);
  435. # else
  436. DEFINE_REAL(char*, index, const char *string, int c)
  437. # endif
  438. # endif
  439. #endif // ASAN_INTERCEPT_INDEX
  440. // For both strcat() and strncat() we need to check the validity of |to|
  441. // argument irrespective of the |from| length.
  442. INTERCEPTOR(char *, strcat, char *to, const char *from) {
  443. void *ctx;
  444. ASAN_INTERCEPTOR_ENTER(ctx, strcat);
  445. AsanInitFromRtl();
  446. if (flags()->replace_str) {
  447. uptr from_length = internal_strlen(from);
  448. ASAN_READ_RANGE(ctx, from, from_length + 1);
  449. uptr to_length = internal_strlen(to);
  450. ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
  451. ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
  452. // If the copying actually happens, the |from| string should not overlap
  453. // with the resulting string starting at |to|, which has a length of
  454. // to_length + from_length + 1.
  455. if (from_length > 0) {
  456. CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, from,
  457. from_length + 1);
  458. }
  459. }
  460. return REAL(strcat)(to, from);
  461. }
  462. INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
  463. void *ctx;
  464. ASAN_INTERCEPTOR_ENTER(ctx, strncat);
  465. AsanInitFromRtl();
  466. if (flags()->replace_str) {
  467. uptr from_length = MaybeRealStrnlen(from, size);
  468. uptr copy_length = Min(size, from_length + 1);
  469. ASAN_READ_RANGE(ctx, from, copy_length);
  470. uptr to_length = internal_strlen(to);
  471. ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
  472. ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
  473. if (from_length > 0) {
  474. CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1,
  475. from, copy_length);
  476. }
  477. }
  478. return REAL(strncat)(to, from, size);
  479. }
  480. INTERCEPTOR(char *, strcpy, char *to, const char *from) {
  481. void *ctx;
  482. ASAN_INTERCEPTOR_ENTER(ctx, strcpy);
  483. if constexpr (SANITIZER_APPLE) {
  484. // strcpy is called from malloc_default_purgeable_zone()
  485. // in __asan::ReplaceSystemAlloc() on Mac.
  486. if (UNLIKELY(!AsanInited()))
  487. return REAL(strcpy)(to, from);
  488. } else {
  489. if (!TryAsanInitFromRtl())
  490. return REAL(strcpy)(to, from);
  491. }
  492. if (flags()->replace_str) {
  493. uptr from_size = internal_strlen(from) + 1;
  494. CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
  495. ASAN_READ_RANGE(ctx, from, from_size);
  496. ASAN_WRITE_RANGE(ctx, to, from_size);
  497. }
  498. return REAL(strcpy)(to, from);
  499. }
  500. INTERCEPTOR(char*, strdup, const char *s) {
  501. void *ctx;
  502. ASAN_INTERCEPTOR_ENTER(ctx, strdup);
  503. if (UNLIKELY(!TryAsanInitFromRtl()))
  504. return internal_strdup(s);
  505. uptr length = internal_strlen(s);
  506. if (flags()->replace_str) {
  507. ASAN_READ_RANGE(ctx, s, length + 1);
  508. }
  509. GET_STACK_TRACE_MALLOC;
  510. void *new_mem = asan_malloc(length + 1, &stack);
  511. if (new_mem) {
  512. REAL(memcpy)(new_mem, s, length + 1);
  513. }
  514. return reinterpret_cast<char*>(new_mem);
  515. }
  516. #if ASAN_INTERCEPT___STRDUP
  517. INTERCEPTOR(char*, __strdup, const char *s) {
  518. void *ctx;
  519. ASAN_INTERCEPTOR_ENTER(ctx, strdup);
  520. if (UNLIKELY(!TryAsanInitFromRtl()))
  521. return internal_strdup(s);
  522. uptr length = internal_strlen(s);
  523. if (flags()->replace_str) {
  524. ASAN_READ_RANGE(ctx, s, length + 1);
  525. }
  526. GET_STACK_TRACE_MALLOC;
  527. void *new_mem = asan_malloc(length + 1, &stack);
  528. if (new_mem) {
  529. REAL(memcpy)(new_mem, s, length + 1);
  530. }
  531. return reinterpret_cast<char*>(new_mem);
  532. }
  533. #endif // ASAN_INTERCEPT___STRDUP
  534. INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
  535. void *ctx;
  536. ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
  537. AsanInitFromRtl();
  538. if (flags()->replace_str) {
  539. uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
  540. CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
  541. ASAN_READ_RANGE(ctx, from, from_size);
  542. ASAN_WRITE_RANGE(ctx, to, size);
  543. }
  544. return REAL(strncpy)(to, from, size);
  545. }
  546. template <typename Fn>
  547. static ALWAYS_INLINE auto StrtolImpl(void *ctx, Fn real, const char *nptr,
  548. char **endptr, int base)
  549. -> decltype(real(nullptr, nullptr, 0)) {
  550. if (!flags()->replace_str)
  551. return real(nptr, endptr, base);
  552. char *real_endptr;
  553. auto res = real(nptr, &real_endptr, base);
  554. StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
  555. return res;
  556. }
  557. # define INTERCEPTOR_STRTO_BASE(ret_type, func) \
  558. INTERCEPTOR(ret_type, func, const char *nptr, char **endptr, int base) { \
  559. void *ctx; \
  560. ASAN_INTERCEPTOR_ENTER(ctx, func); \
  561. AsanInitFromRtl(); \
  562. return StrtolImpl(ctx, REAL(func), nptr, endptr, base); \
  563. }
  564. INTERCEPTOR_STRTO_BASE(long, strtol)
  565. INTERCEPTOR_STRTO_BASE(long long, strtoll)
  566. # if SANITIZER_GLIBC
  567. INTERCEPTOR_STRTO_BASE(long, __isoc23_strtol)
  568. INTERCEPTOR_STRTO_BASE(long long, __isoc23_strtoll)
  569. # endif
  570. INTERCEPTOR(int, atoi, const char *nptr) {
  571. void *ctx;
  572. ASAN_INTERCEPTOR_ENTER(ctx, atoi);
  573. if (SANITIZER_APPLE && UNLIKELY(!AsanInited()))
  574. return REAL(atoi)(nptr);
  575. AsanInitFromRtl();
  576. if (!flags()->replace_str) {
  577. return REAL(atoi)(nptr);
  578. }
  579. char *real_endptr;
  580. // "man atoi" tells that behavior of atoi(nptr) is the same as
  581. // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the
  582. // parsed integer can't be stored in *long* type (even if it's
  583. // different from int). So, we just imitate this behavior.
  584. int result = REAL(strtol)(nptr, &real_endptr, 10);
  585. FixRealStrtolEndptr(nptr, &real_endptr);
  586. ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
  587. return result;
  588. }
  589. INTERCEPTOR(long, atol, const char *nptr) {
  590. void *ctx;
  591. ASAN_INTERCEPTOR_ENTER(ctx, atol);
  592. if (SANITIZER_APPLE && UNLIKELY(!AsanInited()))
  593. return REAL(atol)(nptr);
  594. AsanInitFromRtl();
  595. if (!flags()->replace_str) {
  596. return REAL(atol)(nptr);
  597. }
  598. char *real_endptr;
  599. long result = REAL(strtol)(nptr, &real_endptr, 10);
  600. FixRealStrtolEndptr(nptr, &real_endptr);
  601. ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
  602. return result;
  603. }
  604. INTERCEPTOR(long long, atoll, const char *nptr) {
  605. void *ctx;
  606. ASAN_INTERCEPTOR_ENTER(ctx, atoll);
  607. AsanInitFromRtl();
  608. if (!flags()->replace_str) {
  609. return REAL(atoll)(nptr);
  610. }
  611. char *real_endptr;
  612. long long result = REAL(strtoll)(nptr, &real_endptr, 10);
  613. FixRealStrtolEndptr(nptr, &real_endptr);
  614. ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
  615. return result;
  616. }
  617. #if ASAN_INTERCEPT___CXA_ATEXIT || ASAN_INTERCEPT_ATEXIT
  618. static void AtCxaAtexit(void *unused) {
  619. (void)unused;
  620. StopInitOrderChecking();
  621. }
  622. #endif
  623. #if ASAN_INTERCEPT___CXA_ATEXIT
  624. INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
  625. void *dso_handle) {
  626. if (SANITIZER_APPLE && UNLIKELY(!AsanInited()))
  627. return REAL(__cxa_atexit)(func, arg, dso_handle);
  628. AsanInitFromRtl();
  629. # if CAN_SANITIZE_LEAKS
  630. __lsan::ScopedInterceptorDisabler disabler;
  631. #endif
  632. int res = REAL(__cxa_atexit)(func, arg, dso_handle);
  633. REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
  634. return res;
  635. }
  636. #endif // ASAN_INTERCEPT___CXA_ATEXIT
  637. #if ASAN_INTERCEPT_ATEXIT
  638. INTERCEPTOR(int, atexit, void (*func)()) {
  639. AsanInitFromRtl();
  640. # if CAN_SANITIZE_LEAKS
  641. __lsan::ScopedInterceptorDisabler disabler;
  642. #endif
  643. // Avoid calling real atexit as it is unreachable on at least on Linux.
  644. int res = REAL(__cxa_atexit)((void (*)(void *a))func, nullptr, nullptr);
  645. REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
  646. return res;
  647. }
  648. #endif
  649. #if ASAN_INTERCEPT_PTHREAD_ATFORK
  650. extern "C" {
  651. extern int _pthread_atfork(void (*prepare)(), void (*parent)(),
  652. void (*child)());
  653. };
  654. INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(),
  655. void (*child)()) {
  656. #if CAN_SANITIZE_LEAKS
  657. __lsan::ScopedInterceptorDisabler disabler;
  658. #endif
  659. // REAL(pthread_atfork) cannot be called due to symbol indirections at least
  660. // on NetBSD
  661. return _pthread_atfork(prepare, parent, child);
  662. }
  663. #endif
  664. #if ASAN_INTERCEPT_VFORK
  665. DEFINE_REAL(int, vfork)
  666. DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork)
  667. #endif
  668. // ---------------------- InitializeAsanInterceptors ---------------- {{{1
  669. namespace __asan {
  670. void InitializeAsanInterceptors() {
  671. static bool was_called_once;
  672. CHECK(!was_called_once);
  673. was_called_once = true;
  674. InitializePlatformInterceptors();
  675. InitializeCommonInterceptors();
  676. InitializeSignalInterceptors();
  677. // Intercept str* functions.
  678. ASAN_INTERCEPT_FUNC(strcat);
  679. ASAN_INTERCEPT_FUNC(strcpy);
  680. ASAN_INTERCEPT_FUNC(strncat);
  681. ASAN_INTERCEPT_FUNC(strncpy);
  682. ASAN_INTERCEPT_FUNC(strdup);
  683. #if ASAN_INTERCEPT___STRDUP
  684. ASAN_INTERCEPT_FUNC(__strdup);
  685. #endif
  686. #if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
  687. ASAN_INTERCEPT_FUNC(index);
  688. #endif
  689. ASAN_INTERCEPT_FUNC(atoi);
  690. ASAN_INTERCEPT_FUNC(atol);
  691. ASAN_INTERCEPT_FUNC(atoll);
  692. ASAN_INTERCEPT_FUNC(strtol);
  693. ASAN_INTERCEPT_FUNC(strtoll);
  694. # if SANITIZER_GLIBC
  695. ASAN_INTERCEPT_FUNC(__isoc23_strtol);
  696. ASAN_INTERCEPT_FUNC(__isoc23_strtoll);
  697. # endif
  698. // Intecept jump-related functions.
  699. ASAN_INTERCEPT_FUNC(longjmp);
  700. # if ASAN_INTERCEPT_SWAPCONTEXT
  701. ASAN_INTERCEPT_FUNC(swapcontext);
  702. ASAN_INTERCEPT_FUNC(makecontext);
  703. # endif
  704. # if ASAN_INTERCEPT__LONGJMP
  705. ASAN_INTERCEPT_FUNC(_longjmp);
  706. #endif
  707. #if ASAN_INTERCEPT___LONGJMP_CHK
  708. ASAN_INTERCEPT_FUNC(__longjmp_chk);
  709. #endif
  710. #if ASAN_INTERCEPT_SIGLONGJMP
  711. ASAN_INTERCEPT_FUNC(siglongjmp);
  712. #endif
  713. // Intercept exception handling functions.
  714. #if ASAN_INTERCEPT___CXA_THROW
  715. ASAN_INTERCEPT_FUNC(__cxa_throw);
  716. #endif
  717. #if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION
  718. ASAN_INTERCEPT_FUNC(__cxa_rethrow_primary_exception);
  719. #endif
  720. // Indirectly intercept std::rethrow_exception.
  721. #if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION
  722. ASAN_INTERCEPT_FUNC(_Unwind_RaiseException);
  723. #endif
  724. // Indirectly intercept std::rethrow_exception.
  725. #if ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION
  726. ASAN_INTERCEPT_FUNC(_Unwind_SjLj_RaiseException);
  727. #endif
  728. // Intercept threading-related functions
  729. #if ASAN_INTERCEPT_PTHREAD_CREATE
  730. // TODO: this should probably have an unversioned fallback for newer arches?
  731. #if defined(ASAN_PTHREAD_CREATE_VERSION)
  732. ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION);
  733. #else
  734. ASAN_INTERCEPT_FUNC(pthread_create);
  735. #endif
  736. ASAN_INTERCEPT_FUNC(pthread_join);
  737. ASAN_INTERCEPT_FUNC(pthread_detach);
  738. ASAN_INTERCEPT_FUNC(pthread_exit);
  739. # endif
  740. # if ASAN_INTERCEPT_TIMEDJOIN
  741. ASAN_INTERCEPT_FUNC(pthread_timedjoin_np);
  742. #endif
  743. #if ASAN_INTERCEPT_TRYJOIN
  744. ASAN_INTERCEPT_FUNC(pthread_tryjoin_np);
  745. #endif
  746. // Intercept atexit function.
  747. #if ASAN_INTERCEPT___CXA_ATEXIT
  748. ASAN_INTERCEPT_FUNC(__cxa_atexit);
  749. #endif
  750. #if ASAN_INTERCEPT_ATEXIT
  751. ASAN_INTERCEPT_FUNC(atexit);
  752. #endif
  753. #if ASAN_INTERCEPT_PTHREAD_ATFORK
  754. ASAN_INTERCEPT_FUNC(pthread_atfork);
  755. #endif
  756. #if ASAN_INTERCEPT_VFORK
  757. ASAN_INTERCEPT_FUNC(vfork);
  758. #endif
  759. VReport(1, "AddressSanitizer: libc interceptors initialized\n");
  760. }
  761. } // namespace __asan
  762. #endif // !SANITIZER_FUCHSIA