asan_errors.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. //===-- asan_errors.h -------------------------------------------*- C++ -*-===//
  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. // ASan-private header for error structures.
  12. //===----------------------------------------------------------------------===//
  13. #ifndef ASAN_ERRORS_H
  14. #define ASAN_ERRORS_H
  15. #include "asan_descriptions.h"
  16. #include "asan_scariness_score.h"
  17. #include "sanitizer_common/sanitizer_common.h"
  18. namespace __asan {
  19. // (*) VS2013 does not implement unrestricted unions, so we need a trivial
  20. // default constructor explicitly defined for each particular error.
  21. // None of the error classes own the stack traces mentioned in them.
  22. struct ErrorBase {
  23. ScarinessScoreBase scariness;
  24. u32 tid;
  25. ErrorBase() = default; // (*)
  26. explicit ErrorBase(u32 tid_) : tid(tid_) {}
  27. ErrorBase(u32 tid_, int initial_score, const char *reason) : tid(tid_) {
  28. scariness.Clear();
  29. scariness.Scare(initial_score, reason);
  30. }
  31. };
  32. struct ErrorDeadlySignal : ErrorBase {
  33. SignalContext signal;
  34. ErrorDeadlySignal() = default; // (*)
  35. ErrorDeadlySignal(u32 tid, const SignalContext &sig)
  36. : ErrorBase(tid),
  37. signal(sig) {
  38. scariness.Clear();
  39. if (signal.IsStackOverflow()) {
  40. scariness.Scare(10, "stack-overflow");
  41. } else if (!signal.is_memory_access) {
  42. scariness.Scare(10, "signal");
  43. } else if (signal.is_true_faulting_addr &&
  44. signal.addr < GetPageSizeCached()) {
  45. scariness.Scare(10, "null-deref");
  46. } else if (signal.addr == signal.pc) {
  47. scariness.Scare(60, "wild-jump");
  48. } else if (signal.write_flag == SignalContext::WRITE) {
  49. scariness.Scare(30, "wild-addr-write");
  50. } else if (signal.write_flag == SignalContext::READ) {
  51. scariness.Scare(20, "wild-addr-read");
  52. } else {
  53. scariness.Scare(25, "wild-addr");
  54. }
  55. }
  56. void Print();
  57. };
  58. struct ErrorDoubleFree : ErrorBase {
  59. const BufferedStackTrace *second_free_stack;
  60. HeapAddressDescription addr_description;
  61. ErrorDoubleFree() = default; // (*)
  62. ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr)
  63. : ErrorBase(tid, 42, "double-free"),
  64. second_free_stack(stack) {
  65. CHECK_GT(second_free_stack->size, 0);
  66. GetHeapAddressInformation(addr, 1, &addr_description);
  67. }
  68. void Print();
  69. };
  70. struct ErrorNewDeleteTypeMismatch : ErrorBase {
  71. const BufferedStackTrace *free_stack;
  72. HeapAddressDescription addr_description;
  73. uptr delete_size;
  74. uptr delete_alignment;
  75. ErrorNewDeleteTypeMismatch() = default; // (*)
  76. ErrorNewDeleteTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
  77. uptr delete_size_, uptr delete_alignment_)
  78. : ErrorBase(tid, 10, "new-delete-type-mismatch"),
  79. free_stack(stack),
  80. delete_size(delete_size_),
  81. delete_alignment(delete_alignment_) {
  82. GetHeapAddressInformation(addr, 1, &addr_description);
  83. }
  84. void Print();
  85. };
  86. struct ErrorFreeNotMalloced : ErrorBase {
  87. const BufferedStackTrace *free_stack;
  88. AddressDescription addr_description;
  89. ErrorFreeNotMalloced() = default; // (*)
  90. ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr)
  91. : ErrorBase(tid, 40, "bad-free"),
  92. free_stack(stack),
  93. addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
  94. void Print();
  95. };
  96. struct ErrorAllocTypeMismatch : ErrorBase {
  97. const BufferedStackTrace *dealloc_stack;
  98. AllocType alloc_type, dealloc_type;
  99. AddressDescription addr_description;
  100. ErrorAllocTypeMismatch() = default; // (*)
  101. ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
  102. AllocType alloc_type_, AllocType dealloc_type_)
  103. : ErrorBase(tid, 10, "alloc-dealloc-mismatch"),
  104. dealloc_stack(stack),
  105. alloc_type(alloc_type_),
  106. dealloc_type(dealloc_type_),
  107. addr_description(addr, 1, false) {}
  108. void Print();
  109. };
  110. struct ErrorMallocUsableSizeNotOwned : ErrorBase {
  111. const BufferedStackTrace *stack;
  112. AddressDescription addr_description;
  113. ErrorMallocUsableSizeNotOwned() = default; // (*)
  114. ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr)
  115. : ErrorBase(tid, 10, "bad-malloc_usable_size"),
  116. stack(stack_),
  117. addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
  118. void Print();
  119. };
  120. struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
  121. const BufferedStackTrace *stack;
  122. AddressDescription addr_description;
  123. ErrorSanitizerGetAllocatedSizeNotOwned() = default; // (*)
  124. ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_,
  125. uptr addr)
  126. : ErrorBase(tid, 10, "bad-__sanitizer_get_allocated_size"),
  127. stack(stack_),
  128. addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
  129. void Print();
  130. };
  131. struct ErrorCallocOverflow : ErrorBase {
  132. const BufferedStackTrace *stack;
  133. uptr count;
  134. uptr size;
  135. ErrorCallocOverflow() = default; // (*)
  136. ErrorCallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
  137. uptr size_)
  138. : ErrorBase(tid, 10, "calloc-overflow"),
  139. stack(stack_),
  140. count(count_),
  141. size(size_) {}
  142. void Print();
  143. };
  144. struct ErrorReallocArrayOverflow : ErrorBase {
  145. const BufferedStackTrace *stack;
  146. uptr count;
  147. uptr size;
  148. ErrorReallocArrayOverflow() = default; // (*)
  149. ErrorReallocArrayOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
  150. uptr size_)
  151. : ErrorBase(tid, 10, "reallocarray-overflow"),
  152. stack(stack_),
  153. count(count_),
  154. size(size_) {}
  155. void Print();
  156. };
  157. struct ErrorPvallocOverflow : ErrorBase {
  158. const BufferedStackTrace *stack;
  159. uptr size;
  160. ErrorPvallocOverflow() = default; // (*)
  161. ErrorPvallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr size_)
  162. : ErrorBase(tid, 10, "pvalloc-overflow"),
  163. stack(stack_),
  164. size(size_) {}
  165. void Print();
  166. };
  167. struct ErrorInvalidAllocationAlignment : ErrorBase {
  168. const BufferedStackTrace *stack;
  169. uptr alignment;
  170. ErrorInvalidAllocationAlignment() = default; // (*)
  171. ErrorInvalidAllocationAlignment(u32 tid, BufferedStackTrace *stack_,
  172. uptr alignment_)
  173. : ErrorBase(tid, 10, "invalid-allocation-alignment"),
  174. stack(stack_),
  175. alignment(alignment_) {}
  176. void Print();
  177. };
  178. struct ErrorInvalidAlignedAllocAlignment : ErrorBase {
  179. const BufferedStackTrace *stack;
  180. uptr size;
  181. uptr alignment;
  182. ErrorInvalidAlignedAllocAlignment() = default; // (*)
  183. ErrorInvalidAlignedAllocAlignment(u32 tid, BufferedStackTrace *stack_,
  184. uptr size_, uptr alignment_)
  185. : ErrorBase(tid, 10, "invalid-aligned-alloc-alignment"),
  186. stack(stack_),
  187. size(size_),
  188. alignment(alignment_) {}
  189. void Print();
  190. };
  191. struct ErrorInvalidPosixMemalignAlignment : ErrorBase {
  192. const BufferedStackTrace *stack;
  193. uptr alignment;
  194. ErrorInvalidPosixMemalignAlignment() = default; // (*)
  195. ErrorInvalidPosixMemalignAlignment(u32 tid, BufferedStackTrace *stack_,
  196. uptr alignment_)
  197. : ErrorBase(tid, 10, "invalid-posix-memalign-alignment"),
  198. stack(stack_),
  199. alignment(alignment_) {}
  200. void Print();
  201. };
  202. struct ErrorAllocationSizeTooBig : ErrorBase {
  203. const BufferedStackTrace *stack;
  204. uptr user_size;
  205. uptr total_size;
  206. uptr max_size;
  207. ErrorAllocationSizeTooBig() = default; // (*)
  208. ErrorAllocationSizeTooBig(u32 tid, BufferedStackTrace *stack_,
  209. uptr user_size_, uptr total_size_, uptr max_size_)
  210. : ErrorBase(tid, 10, "allocation-size-too-big"),
  211. stack(stack_),
  212. user_size(user_size_),
  213. total_size(total_size_),
  214. max_size(max_size_) {}
  215. void Print();
  216. };
  217. struct ErrorRssLimitExceeded : ErrorBase {
  218. const BufferedStackTrace *stack;
  219. ErrorRssLimitExceeded() = default; // (*)
  220. ErrorRssLimitExceeded(u32 tid, BufferedStackTrace *stack_)
  221. : ErrorBase(tid, 10, "rss-limit-exceeded"),
  222. stack(stack_) {}
  223. void Print();
  224. };
  225. struct ErrorOutOfMemory : ErrorBase {
  226. const BufferedStackTrace *stack;
  227. uptr requested_size;
  228. ErrorOutOfMemory() = default; // (*)
  229. ErrorOutOfMemory(u32 tid, BufferedStackTrace *stack_, uptr requested_size_)
  230. : ErrorBase(tid, 10, "out-of-memory"),
  231. stack(stack_),
  232. requested_size(requested_size_) {}
  233. void Print();
  234. };
  235. struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
  236. const BufferedStackTrace *stack;
  237. uptr length1, length2;
  238. AddressDescription addr1_description;
  239. AddressDescription addr2_description;
  240. const char *function;
  241. ErrorStringFunctionMemoryRangesOverlap() = default; // (*)
  242. ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_,
  243. uptr addr1, uptr length1_, uptr addr2,
  244. uptr length2_, const char *function_)
  245. : ErrorBase(tid),
  246. stack(stack_),
  247. length1(length1_),
  248. length2(length2_),
  249. addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false),
  250. addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false),
  251. function(function_) {
  252. char bug_type[100];
  253. internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
  254. scariness.Clear();
  255. scariness.Scare(10, bug_type);
  256. }
  257. void Print();
  258. };
  259. struct ErrorStringFunctionSizeOverflow : ErrorBase {
  260. const BufferedStackTrace *stack;
  261. AddressDescription addr_description;
  262. uptr size;
  263. ErrorStringFunctionSizeOverflow() = default; // (*)
  264. ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_,
  265. uptr addr, uptr size_)
  266. : ErrorBase(tid, 10, "negative-size-param"),
  267. stack(stack_),
  268. addr_description(addr, /*shouldLockThreadRegistry=*/false),
  269. size(size_) {}
  270. void Print();
  271. };
  272. struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
  273. const BufferedStackTrace *stack;
  274. uptr beg, end, old_mid, new_mid;
  275. ErrorBadParamsToAnnotateContiguousContainer() = default; // (*)
  276. // PS4: Do we want an AddressDescription for beg?
  277. ErrorBadParamsToAnnotateContiguousContainer(u32 tid,
  278. BufferedStackTrace *stack_,
  279. uptr beg_, uptr end_,
  280. uptr old_mid_, uptr new_mid_)
  281. : ErrorBase(tid, 10, "bad-__sanitizer_annotate_contiguous_container"),
  282. stack(stack_),
  283. beg(beg_),
  284. end(end_),
  285. old_mid(old_mid_),
  286. new_mid(new_mid_) {}
  287. void Print();
  288. };
  289. struct ErrorODRViolation : ErrorBase {
  290. __asan_global global1, global2;
  291. u32 stack_id1, stack_id2;
  292. ErrorODRViolation() = default; // (*)
  293. ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_,
  294. const __asan_global *g2, u32 stack_id2_)
  295. : ErrorBase(tid, 10, "odr-violation"),
  296. global1(*g1),
  297. global2(*g2),
  298. stack_id1(stack_id1_),
  299. stack_id2(stack_id2_) {}
  300. void Print();
  301. };
  302. struct ErrorInvalidPointerPair : ErrorBase {
  303. uptr pc, bp, sp;
  304. AddressDescription addr1_description;
  305. AddressDescription addr2_description;
  306. ErrorInvalidPointerPair() = default; // (*)
  307. ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1,
  308. uptr p2)
  309. : ErrorBase(tid, 10, "invalid-pointer-pair"),
  310. pc(pc_),
  311. bp(bp_),
  312. sp(sp_),
  313. addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
  314. addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {}
  315. void Print();
  316. };
  317. struct ErrorGeneric : ErrorBase {
  318. AddressDescription addr_description;
  319. uptr pc, bp, sp;
  320. uptr access_size;
  321. const char *bug_descr;
  322. bool is_write;
  323. u8 shadow_val;
  324. ErrorGeneric() = default; // (*)
  325. ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_,
  326. uptr access_size_);
  327. void Print();
  328. };
  329. // clang-format off
  330. #define ASAN_FOR_EACH_ERROR_KIND(macro) \
  331. macro(DeadlySignal) \
  332. macro(DoubleFree) \
  333. macro(NewDeleteTypeMismatch) \
  334. macro(FreeNotMalloced) \
  335. macro(AllocTypeMismatch) \
  336. macro(MallocUsableSizeNotOwned) \
  337. macro(SanitizerGetAllocatedSizeNotOwned) \
  338. macro(CallocOverflow) \
  339. macro(ReallocArrayOverflow) \
  340. macro(PvallocOverflow) \
  341. macro(InvalidAllocationAlignment) \
  342. macro(InvalidAlignedAllocAlignment) \
  343. macro(InvalidPosixMemalignAlignment) \
  344. macro(AllocationSizeTooBig) \
  345. macro(RssLimitExceeded) \
  346. macro(OutOfMemory) \
  347. macro(StringFunctionMemoryRangesOverlap) \
  348. macro(StringFunctionSizeOverflow) \
  349. macro(BadParamsToAnnotateContiguousContainer) \
  350. macro(ODRViolation) \
  351. macro(InvalidPointerPair) \
  352. macro(Generic)
  353. // clang-format on
  354. #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
  355. #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
  356. #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
  357. ErrorDescription(Error##name const &e) : kind(kErrorKind##name) { \
  358. internal_memcpy(&name, &e, sizeof(name)); \
  359. }
  360. #define ASAN_ERROR_DESCRIPTION_PRINT(name) \
  361. case kErrorKind##name: \
  362. return name.Print();
  363. enum ErrorKind {
  364. kErrorKindInvalid = 0,
  365. ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND)
  366. };
  367. struct ErrorDescription {
  368. ErrorKind kind;
  369. // We're using a tagged union because it allows us to have a trivially
  370. // copiable type and use the same structures as the public interface.
  371. //
  372. // We can add a wrapper around it to make it "more c++-like", but that would
  373. // add a lot of code and the benefit wouldn't be that big.
  374. union {
  375. ErrorBase Base;
  376. ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
  377. };
  378. ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
  379. explicit ErrorDescription(LinkerInitialized) {}
  380. ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR)
  381. bool IsValid() { return kind != kErrorKindInvalid; }
  382. void Print() {
  383. switch (kind) {
  384. ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT)
  385. case kErrorKindInvalid:
  386. CHECK(0);
  387. }
  388. CHECK(0);
  389. }
  390. };
  391. #undef ASAN_FOR_EACH_ERROR_KIND
  392. #undef ASAN_DEFINE_ERROR_KIND
  393. #undef ASAN_ERROR_DESCRIPTION_MEMBER
  394. #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
  395. #undef ASAN_ERROR_DESCRIPTION_PRINT
  396. } // namespace __asan
  397. #endif // ASAN_ERRORS_H