1 | //===-- sanitizer_allocator_checks.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 | // Various checks shared between ThreadSanitizer, MemorySanitizer, etc. memory |
10 | // allocators. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef SANITIZER_ALLOCATOR_CHECKS_H |
15 | #define SANITIZER_ALLOCATOR_CHECKS_H |
16 | |
17 | #include "sanitizer_internal_defs.h" |
18 | #include "sanitizer_common.h" |
19 | #include "sanitizer_platform.h" |
20 | |
21 | namespace __sanitizer { |
22 | |
23 | // The following is defined in a separate compilation unit to avoid pulling in |
24 | // sanitizer_errno.h in this header, which leads to conflicts when other system |
25 | // headers include errno.h. This is usually the result of an unlikely event, |
26 | // and as such we do not care as much about having it inlined. |
27 | void SetErrnoToENOMEM(); |
28 | |
29 | // A common errno setting logic shared by almost all sanitizer allocator APIs. |
30 | inline void *SetErrnoOnNull(void *ptr) { |
31 | if (UNLIKELY(!ptr)) |
32 | SetErrnoToENOMEM(); |
33 | return ptr; |
34 | } |
35 | |
36 | // In case of the check failure, the caller of the following Check... functions |
37 | // should "return POLICY::OnBadRequest();" where POLICY is the current allocator |
38 | // failure handling policy. |
39 | |
40 | // Checks aligned_alloc() parameters, verifies that the alignment is a power of |
41 | // two and that the size is a multiple of alignment for POSIX implementation, |
42 | // and a bit relaxed requirement for non-POSIX ones, that the size is a multiple |
43 | // of alignment. |
44 | inline bool CheckAlignedAllocAlignmentAndSize(uptr alignment, uptr size) { |
45 | #if SANITIZER_POSIX |
46 | return alignment != 0 && IsPowerOfTwo(x: alignment) && |
47 | (size & (alignment - 1)) == 0; |
48 | #else |
49 | return alignment != 0 && size % alignment == 0; |
50 | #endif |
51 | } |
52 | |
53 | // Checks posix_memalign() parameters, verifies that alignment is a power of two |
54 | // and a multiple of sizeof(void *). |
55 | inline bool CheckPosixMemalignAlignment(uptr alignment) { |
56 | return alignment != 0 && IsPowerOfTwo(x: alignment) && |
57 | (alignment % sizeof(void *)) == 0; |
58 | } |
59 | |
60 | // Returns true if calloc(size, n) call overflows on size*n calculation. |
61 | inline bool CheckForCallocOverflow(uptr size, uptr n) { |
62 | if (!size) |
63 | return false; |
64 | uptr max = (uptr)-1L; |
65 | return (max / size) < n; |
66 | } |
67 | |
68 | // Returns true if the size passed to pvalloc overflows when rounded to the next |
69 | // multiple of page_size. |
70 | inline bool CheckForPvallocOverflow(uptr size, uptr page_size) { |
71 | return RoundUpTo(size, boundary: page_size) < size; |
72 | } |
73 | |
74 | } // namespace __sanitizer |
75 | |
76 | #endif // SANITIZER_ALLOCATOR_CHECKS_H |
77 | |