xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_allocator.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1fe6060f1SDimitry Andric //===-- dfsan_allocator.cpp -------------------------- --------------------===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric //
9fe6060f1SDimitry Andric // This file is a part of DataflowSanitizer.
10fe6060f1SDimitry Andric //
11fe6060f1SDimitry Andric // DataflowSanitizer allocator.
12fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
13fe6060f1SDimitry Andric 
14fe6060f1SDimitry Andric #include "dfsan_allocator.h"
15fe6060f1SDimitry Andric 
16fe6060f1SDimitry Andric #include "dfsan.h"
17fe6060f1SDimitry Andric #include "dfsan_flags.h"
18fe6060f1SDimitry Andric #include "dfsan_thread.h"
19fe6060f1SDimitry Andric #include "sanitizer_common/sanitizer_allocator.h"
20fe6060f1SDimitry Andric #include "sanitizer_common/sanitizer_allocator_checks.h"
21fe6060f1SDimitry Andric #include "sanitizer_common/sanitizer_allocator_interface.h"
22fe6060f1SDimitry Andric #include "sanitizer_common/sanitizer_allocator_report.h"
23fe6060f1SDimitry Andric #include "sanitizer_common/sanitizer_errno.h"
24fe6060f1SDimitry Andric 
25fe6060f1SDimitry Andric namespace __dfsan {
26fe6060f1SDimitry Andric 
27fe6060f1SDimitry Andric struct Metadata {
28fe6060f1SDimitry Andric   uptr requested_size;
29fe6060f1SDimitry Andric };
30fe6060f1SDimitry Andric 
31fe6060f1SDimitry Andric struct DFsanMapUnmapCallback {
32fe6060f1SDimitry Andric   void OnMap(uptr p, uptr size) const { dfsan_set_label(0, (void *)p, size); }
3306c3fb27SDimitry Andric   void OnMapSecondary(uptr p, uptr size, uptr user_begin,
3406c3fb27SDimitry Andric                       uptr user_size) const {
3506c3fb27SDimitry Andric     OnMap(p, size);
3606c3fb27SDimitry Andric   }
37fe6060f1SDimitry Andric   void OnUnmap(uptr p, uptr size) const { dfsan_set_label(0, (void *)p, size); }
38fe6060f1SDimitry Andric };
39fe6060f1SDimitry Andric 
40*0fca6ea1SDimitry Andric // Note: to ensure that the allocator is compatible with the application memory
41*0fca6ea1SDimitry Andric // layout (especially with high-entropy ASLR), kSpaceBeg and kSpaceSize must be
42*0fca6ea1SDimitry Andric // duplicated as MappingDesc::ALLOCATOR in dfsan_platform.h.
43bdd1243dSDimitry Andric #if defined(__aarch64__)
44bdd1243dSDimitry Andric const uptr kAllocatorSpace = 0xE00000000000ULL;
45bdd1243dSDimitry Andric #else
46bdd1243dSDimitry Andric const uptr kAllocatorSpace = 0x700000000000ULL;
47bdd1243dSDimitry Andric #endif
48*0fca6ea1SDimitry Andric const uptr kMaxAllowedMallocSize = 1ULL << 40;
49fe6060f1SDimitry Andric 
50fe6060f1SDimitry Andric struct AP64 {  // Allocator64 parameters. Deliberately using a short name.
51fe6060f1SDimitry Andric   static const uptr kSpaceBeg = kAllocatorSpace;
52fe6060f1SDimitry Andric   static const uptr kSpaceSize = 0x40000000000;  // 4T.
53fe6060f1SDimitry Andric   static const uptr kMetadataSize = sizeof(Metadata);
54fe6060f1SDimitry Andric   typedef DefaultSizeClassMap SizeClassMap;
55fe6060f1SDimitry Andric   typedef DFsanMapUnmapCallback MapUnmapCallback;
56fe6060f1SDimitry Andric   static const uptr kFlags = 0;
57fe6060f1SDimitry Andric   using AddressSpaceView = LocalAddressSpaceView;
58fe6060f1SDimitry Andric };
59fe6060f1SDimitry Andric 
60fe6060f1SDimitry Andric typedef SizeClassAllocator64<AP64> PrimaryAllocator;
61fe6060f1SDimitry Andric 
62fe6060f1SDimitry Andric typedef CombinedAllocator<PrimaryAllocator> Allocator;
63fe6060f1SDimitry Andric typedef Allocator::AllocatorCache AllocatorCache;
64fe6060f1SDimitry Andric 
65fe6060f1SDimitry Andric static Allocator allocator;
66fe6060f1SDimitry Andric static AllocatorCache fallback_allocator_cache;
67fe6060f1SDimitry Andric static StaticSpinMutex fallback_mutex;
68fe6060f1SDimitry Andric 
69fe6060f1SDimitry Andric static uptr max_malloc_size;
70fe6060f1SDimitry Andric 
71fe6060f1SDimitry Andric void dfsan_allocator_init() {
72fe6060f1SDimitry Andric   SetAllocatorMayReturnNull(common_flags()->allocator_may_return_null);
73fe6060f1SDimitry Andric   allocator.Init(common_flags()->allocator_release_to_os_interval_ms);
74fe6060f1SDimitry Andric   if (common_flags()->max_allocation_size_mb)
75fe6060f1SDimitry Andric     max_malloc_size = Min(common_flags()->max_allocation_size_mb << 20,
76fe6060f1SDimitry Andric                           kMaxAllowedMallocSize);
77fe6060f1SDimitry Andric   else
78fe6060f1SDimitry Andric     max_malloc_size = kMaxAllowedMallocSize;
79fe6060f1SDimitry Andric }
80fe6060f1SDimitry Andric 
81fe6060f1SDimitry Andric AllocatorCache *GetAllocatorCache(DFsanThreadLocalMallocStorage *ms) {
82fe6060f1SDimitry Andric   CHECK(ms);
83fe6060f1SDimitry Andric   CHECK_LE(sizeof(AllocatorCache), sizeof(ms->allocator_cache));
84fe6060f1SDimitry Andric   return reinterpret_cast<AllocatorCache *>(ms->allocator_cache);
85fe6060f1SDimitry Andric }
86fe6060f1SDimitry Andric 
87fe6060f1SDimitry Andric void DFsanThreadLocalMallocStorage::CommitBack() {
88fe6060f1SDimitry Andric   allocator.SwallowCache(GetAllocatorCache(this));
89fe6060f1SDimitry Andric }
90fe6060f1SDimitry Andric 
91fe6060f1SDimitry Andric static void *DFsanAllocate(uptr size, uptr alignment, bool zeroise) {
92fe6060f1SDimitry Andric   if (size > max_malloc_size) {
93fe6060f1SDimitry Andric     if (AllocatorMayReturnNull()) {
94fe6060f1SDimitry Andric       Report("WARNING: DataflowSanitizer failed to allocate 0x%zx bytes\n",
95fe6060f1SDimitry Andric              size);
96fe6060f1SDimitry Andric       return nullptr;
97fe6060f1SDimitry Andric     }
98fe6060f1SDimitry Andric     BufferedStackTrace stack;
99fe6060f1SDimitry Andric     ReportAllocationSizeTooBig(size, max_malloc_size, &stack);
100fe6060f1SDimitry Andric   }
1010eae32dcSDimitry Andric   if (UNLIKELY(IsRssLimitExceeded())) {
1020eae32dcSDimitry Andric     if (AllocatorMayReturnNull())
1030eae32dcSDimitry Andric       return nullptr;
1040eae32dcSDimitry Andric     BufferedStackTrace stack;
1050eae32dcSDimitry Andric     ReportRssLimitExceeded(&stack);
1060eae32dcSDimitry Andric   }
107fe6060f1SDimitry Andric   DFsanThread *t = GetCurrentThread();
108fe6060f1SDimitry Andric   void *allocated;
109fe6060f1SDimitry Andric   if (t) {
110fe6060f1SDimitry Andric     AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
111fe6060f1SDimitry Andric     allocated = allocator.Allocate(cache, size, alignment);
112fe6060f1SDimitry Andric   } else {
113fe6060f1SDimitry Andric     SpinMutexLock l(&fallback_mutex);
114fe6060f1SDimitry Andric     AllocatorCache *cache = &fallback_allocator_cache;
115fe6060f1SDimitry Andric     allocated = allocator.Allocate(cache, size, alignment);
116fe6060f1SDimitry Andric   }
117fe6060f1SDimitry Andric   if (UNLIKELY(!allocated)) {
118fe6060f1SDimitry Andric     SetAllocatorOutOfMemory();
119fe6060f1SDimitry Andric     if (AllocatorMayReturnNull())
120fe6060f1SDimitry Andric       return nullptr;
121fe6060f1SDimitry Andric     BufferedStackTrace stack;
122fe6060f1SDimitry Andric     ReportOutOfMemory(size, &stack);
123fe6060f1SDimitry Andric   }
124fe6060f1SDimitry Andric   Metadata *meta =
125fe6060f1SDimitry Andric       reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated));
126fe6060f1SDimitry Andric   meta->requested_size = size;
127fe6060f1SDimitry Andric   if (zeroise) {
128fe6060f1SDimitry Andric     internal_memset(allocated, 0, size);
129fe6060f1SDimitry Andric     dfsan_set_label(0, allocated, size);
130fe6060f1SDimitry Andric   } else if (flags().zero_in_malloc) {
131fe6060f1SDimitry Andric     dfsan_set_label(0, allocated, size);
132fe6060f1SDimitry Andric   }
133fe6060f1SDimitry Andric   return allocated;
134fe6060f1SDimitry Andric }
135fe6060f1SDimitry Andric 
136fe6060f1SDimitry Andric void dfsan_deallocate(void *p) {
137fe6060f1SDimitry Andric   CHECK(p);
138fe6060f1SDimitry Andric   Metadata *meta = reinterpret_cast<Metadata *>(allocator.GetMetaData(p));
139fe6060f1SDimitry Andric   uptr size = meta->requested_size;
140fe6060f1SDimitry Andric   meta->requested_size = 0;
141fe6060f1SDimitry Andric   if (flags().zero_in_free)
142fe6060f1SDimitry Andric     dfsan_set_label(0, p, size);
143fe6060f1SDimitry Andric   DFsanThread *t = GetCurrentThread();
144fe6060f1SDimitry Andric   if (t) {
145fe6060f1SDimitry Andric     AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
146fe6060f1SDimitry Andric     allocator.Deallocate(cache, p);
147fe6060f1SDimitry Andric   } else {
148fe6060f1SDimitry Andric     SpinMutexLock l(&fallback_mutex);
149fe6060f1SDimitry Andric     AllocatorCache *cache = &fallback_allocator_cache;
150fe6060f1SDimitry Andric     allocator.Deallocate(cache, p);
151fe6060f1SDimitry Andric   }
152fe6060f1SDimitry Andric }
153fe6060f1SDimitry Andric 
154fe6060f1SDimitry Andric void *DFsanReallocate(void *old_p, uptr new_size, uptr alignment) {
155fe6060f1SDimitry Andric   Metadata *meta = reinterpret_cast<Metadata *>(allocator.GetMetaData(old_p));
156fe6060f1SDimitry Andric   uptr old_size = meta->requested_size;
157fe6060f1SDimitry Andric   uptr actually_allocated_size = allocator.GetActuallyAllocatedSize(old_p);
158fe6060f1SDimitry Andric   if (new_size <= actually_allocated_size) {
159fe6060f1SDimitry Andric     // We are not reallocating here.
160fe6060f1SDimitry Andric     meta->requested_size = new_size;
161fe6060f1SDimitry Andric     if (new_size > old_size && flags().zero_in_malloc)
162fe6060f1SDimitry Andric       dfsan_set_label(0, (char *)old_p + old_size, new_size - old_size);
163fe6060f1SDimitry Andric     return old_p;
164fe6060f1SDimitry Andric   }
165fe6060f1SDimitry Andric   uptr memcpy_size = Min(new_size, old_size);
166fe6060f1SDimitry Andric   void *new_p = DFsanAllocate(new_size, alignment, false /*zeroise*/);
167fe6060f1SDimitry Andric   if (new_p) {
168fe6060f1SDimitry Andric     dfsan_copy_memory(new_p, old_p, memcpy_size);
169fe6060f1SDimitry Andric     dfsan_deallocate(old_p);
170fe6060f1SDimitry Andric   }
171fe6060f1SDimitry Andric   return new_p;
172fe6060f1SDimitry Andric }
173fe6060f1SDimitry Andric 
174fe6060f1SDimitry Andric void *DFsanCalloc(uptr nmemb, uptr size) {
175fe6060f1SDimitry Andric   if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
176fe6060f1SDimitry Andric     if (AllocatorMayReturnNull())
177fe6060f1SDimitry Andric       return nullptr;
178fe6060f1SDimitry Andric     BufferedStackTrace stack;
179fe6060f1SDimitry Andric     ReportCallocOverflow(nmemb, size, &stack);
180fe6060f1SDimitry Andric   }
181fe6060f1SDimitry Andric   return DFsanAllocate(nmemb * size, sizeof(u64), true /*zeroise*/);
182fe6060f1SDimitry Andric }
183fe6060f1SDimitry Andric 
18406c3fb27SDimitry Andric static const void *AllocationBegin(const void *p) {
18506c3fb27SDimitry Andric   if (!p)
18606c3fb27SDimitry Andric     return nullptr;
18706c3fb27SDimitry Andric   void *beg = allocator.GetBlockBegin(p);
18806c3fb27SDimitry Andric   if (!beg)
18906c3fb27SDimitry Andric     return nullptr;
19006c3fb27SDimitry Andric   Metadata *b = (Metadata *)allocator.GetMetaData(beg);
19106c3fb27SDimitry Andric   if (!b)
19206c3fb27SDimitry Andric     return nullptr;
19306c3fb27SDimitry Andric   if (b->requested_size == 0)
19406c3fb27SDimitry Andric     return nullptr;
19506c3fb27SDimitry Andric   return (const void *)beg;
19606c3fb27SDimitry Andric }
19706c3fb27SDimitry Andric 
198fe6060f1SDimitry Andric static uptr AllocationSize(const void *p) {
199fe6060f1SDimitry Andric   if (!p)
200fe6060f1SDimitry Andric     return 0;
201fe6060f1SDimitry Andric   const void *beg = allocator.GetBlockBegin(p);
202fe6060f1SDimitry Andric   if (beg != p)
203fe6060f1SDimitry Andric     return 0;
204fe6060f1SDimitry Andric   Metadata *b = (Metadata *)allocator.GetMetaData(p);
205fe6060f1SDimitry Andric   return b->requested_size;
206fe6060f1SDimitry Andric }
207fe6060f1SDimitry Andric 
20806c3fb27SDimitry Andric static uptr AllocationSizeFast(const void *p) {
20906c3fb27SDimitry Andric   return reinterpret_cast<Metadata *>(allocator.GetMetaData(p))->requested_size;
21006c3fb27SDimitry Andric }
21106c3fb27SDimitry Andric 
212fe6060f1SDimitry Andric void *dfsan_malloc(uptr size) {
213fe6060f1SDimitry Andric   return SetErrnoOnNull(DFsanAllocate(size, sizeof(u64), false /*zeroise*/));
214fe6060f1SDimitry Andric }
215fe6060f1SDimitry Andric 
216fe6060f1SDimitry Andric void *dfsan_calloc(uptr nmemb, uptr size) {
217fe6060f1SDimitry Andric   return SetErrnoOnNull(DFsanCalloc(nmemb, size));
218fe6060f1SDimitry Andric }
219fe6060f1SDimitry Andric 
220fe6060f1SDimitry Andric void *dfsan_realloc(void *ptr, uptr size) {
221fe6060f1SDimitry Andric   if (!ptr)
222fe6060f1SDimitry Andric     return SetErrnoOnNull(DFsanAllocate(size, sizeof(u64), false /*zeroise*/));
223fe6060f1SDimitry Andric   if (size == 0) {
224fe6060f1SDimitry Andric     dfsan_deallocate(ptr);
225fe6060f1SDimitry Andric     return nullptr;
226fe6060f1SDimitry Andric   }
227fe6060f1SDimitry Andric   return SetErrnoOnNull(DFsanReallocate(ptr, size, sizeof(u64)));
228fe6060f1SDimitry Andric }
229fe6060f1SDimitry Andric 
230fe6060f1SDimitry Andric void *dfsan_reallocarray(void *ptr, uptr nmemb, uptr size) {
231fe6060f1SDimitry Andric   if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
232fe6060f1SDimitry Andric     errno = errno_ENOMEM;
233fe6060f1SDimitry Andric     if (AllocatorMayReturnNull())
234fe6060f1SDimitry Andric       return nullptr;
235fe6060f1SDimitry Andric     BufferedStackTrace stack;
236fe6060f1SDimitry Andric     ReportReallocArrayOverflow(nmemb, size, &stack);
237fe6060f1SDimitry Andric   }
238fe6060f1SDimitry Andric   return dfsan_realloc(ptr, nmemb * size);
239fe6060f1SDimitry Andric }
240fe6060f1SDimitry Andric 
241fe6060f1SDimitry Andric void *dfsan_valloc(uptr size) {
242fe6060f1SDimitry Andric   return SetErrnoOnNull(
243fe6060f1SDimitry Andric       DFsanAllocate(size, GetPageSizeCached(), false /*zeroise*/));
244fe6060f1SDimitry Andric }
245fe6060f1SDimitry Andric 
246fe6060f1SDimitry Andric void *dfsan_pvalloc(uptr size) {
247fe6060f1SDimitry Andric   uptr PageSize = GetPageSizeCached();
248fe6060f1SDimitry Andric   if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) {
249fe6060f1SDimitry Andric     errno = errno_ENOMEM;
250fe6060f1SDimitry Andric     if (AllocatorMayReturnNull())
251fe6060f1SDimitry Andric       return nullptr;
252fe6060f1SDimitry Andric     BufferedStackTrace stack;
253fe6060f1SDimitry Andric     ReportPvallocOverflow(size, &stack);
254fe6060f1SDimitry Andric   }
255fe6060f1SDimitry Andric   // pvalloc(0) should allocate one page.
256fe6060f1SDimitry Andric   size = size ? RoundUpTo(size, PageSize) : PageSize;
257fe6060f1SDimitry Andric   return SetErrnoOnNull(DFsanAllocate(size, PageSize, false /*zeroise*/));
258fe6060f1SDimitry Andric }
259fe6060f1SDimitry Andric 
260fe6060f1SDimitry Andric void *dfsan_aligned_alloc(uptr alignment, uptr size) {
261fe6060f1SDimitry Andric   if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) {
262fe6060f1SDimitry Andric     errno = errno_EINVAL;
263fe6060f1SDimitry Andric     if (AllocatorMayReturnNull())
264fe6060f1SDimitry Andric       return nullptr;
265fe6060f1SDimitry Andric     BufferedStackTrace stack;
266fe6060f1SDimitry Andric     ReportInvalidAlignedAllocAlignment(size, alignment, &stack);
267fe6060f1SDimitry Andric   }
268fe6060f1SDimitry Andric   return SetErrnoOnNull(DFsanAllocate(size, alignment, false /*zeroise*/));
269fe6060f1SDimitry Andric }
270fe6060f1SDimitry Andric 
271fe6060f1SDimitry Andric void *dfsan_memalign(uptr alignment, uptr size) {
272fe6060f1SDimitry Andric   if (UNLIKELY(!IsPowerOfTwo(alignment))) {
273fe6060f1SDimitry Andric     errno = errno_EINVAL;
274fe6060f1SDimitry Andric     if (AllocatorMayReturnNull())
275fe6060f1SDimitry Andric       return nullptr;
276fe6060f1SDimitry Andric     BufferedStackTrace stack;
277fe6060f1SDimitry Andric     ReportInvalidAllocationAlignment(alignment, &stack);
278fe6060f1SDimitry Andric   }
279fe6060f1SDimitry Andric   return SetErrnoOnNull(DFsanAllocate(size, alignment, false /*zeroise*/));
280fe6060f1SDimitry Andric }
281fe6060f1SDimitry Andric 
282fe6060f1SDimitry Andric int dfsan_posix_memalign(void **memptr, uptr alignment, uptr size) {
283fe6060f1SDimitry Andric   if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) {
284fe6060f1SDimitry Andric     if (AllocatorMayReturnNull())
285fe6060f1SDimitry Andric       return errno_EINVAL;
286fe6060f1SDimitry Andric     BufferedStackTrace stack;
287fe6060f1SDimitry Andric     ReportInvalidPosixMemalignAlignment(alignment, &stack);
288fe6060f1SDimitry Andric   }
289fe6060f1SDimitry Andric   void *ptr = DFsanAllocate(size, alignment, false /*zeroise*/);
290fe6060f1SDimitry Andric   if (UNLIKELY(!ptr))
291fe6060f1SDimitry Andric     // OOM error is already taken care of by DFsanAllocate.
292fe6060f1SDimitry Andric     return errno_ENOMEM;
293fe6060f1SDimitry Andric   CHECK(IsAligned((uptr)ptr, alignment));
294fe6060f1SDimitry Andric   *memptr = ptr;
295fe6060f1SDimitry Andric   return 0;
296fe6060f1SDimitry Andric }
297fe6060f1SDimitry Andric 
298fe6060f1SDimitry Andric }  // namespace __dfsan
299fe6060f1SDimitry Andric 
300fe6060f1SDimitry Andric using namespace __dfsan;
301fe6060f1SDimitry Andric 
302fe6060f1SDimitry Andric uptr __sanitizer_get_current_allocated_bytes() {
303fe6060f1SDimitry Andric   uptr stats[AllocatorStatCount];
304fe6060f1SDimitry Andric   allocator.GetStats(stats);
305fe6060f1SDimitry Andric   return stats[AllocatorStatAllocated];
306fe6060f1SDimitry Andric }
307fe6060f1SDimitry Andric 
308fe6060f1SDimitry Andric uptr __sanitizer_get_heap_size() {
309fe6060f1SDimitry Andric   uptr stats[AllocatorStatCount];
310fe6060f1SDimitry Andric   allocator.GetStats(stats);
311fe6060f1SDimitry Andric   return stats[AllocatorStatMapped];
312fe6060f1SDimitry Andric }
313fe6060f1SDimitry Andric 
314fe6060f1SDimitry Andric uptr __sanitizer_get_free_bytes() { return 1; }
315fe6060f1SDimitry Andric 
316fe6060f1SDimitry Andric uptr __sanitizer_get_unmapped_bytes() { return 1; }
317fe6060f1SDimitry Andric 
318fe6060f1SDimitry Andric uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }
319fe6060f1SDimitry Andric 
320fe6060f1SDimitry Andric int __sanitizer_get_ownership(const void *p) { return AllocationSize(p) != 0; }
321fe6060f1SDimitry Andric 
32206c3fb27SDimitry Andric const void *__sanitizer_get_allocated_begin(const void *p) {
32306c3fb27SDimitry Andric   return AllocationBegin(p);
32406c3fb27SDimitry Andric }
32506c3fb27SDimitry Andric 
326fe6060f1SDimitry Andric uptr __sanitizer_get_allocated_size(const void *p) { return AllocationSize(p); }
32706c3fb27SDimitry Andric 
32806c3fb27SDimitry Andric uptr __sanitizer_get_allocated_size_fast(const void *p) {
32906c3fb27SDimitry Andric   DCHECK_EQ(p, __sanitizer_get_allocated_begin(p));
33006c3fb27SDimitry Andric   uptr ret = AllocationSizeFast(p);
33106c3fb27SDimitry Andric   DCHECK_EQ(ret, __sanitizer_get_allocated_size(p));
33206c3fb27SDimitry Andric   return ret;
33306c3fb27SDimitry Andric }
334