@@ -205,6 +205,14 @@ QuarantineCache *GetQuarantineCache(AsanThreadLocalMallocStorage *ms) {
205
205
return reinterpret_cast <QuarantineCache *>(ms->quarantine_cache );
206
206
}
207
207
208
+ void AllocatorOptions::SetFrom (const Flags *f, const CommonFlags *cf) {
209
+ quarantine_size_mb = f->quarantine_size >> 20 ;
210
+ min_redzone = f->redzone ;
211
+ max_redzone = f->max_redzone ;
212
+ may_return_null = cf->allocator_may_return_null ;
213
+ alloc_dealloc_mismatch = f->alloc_dealloc_mismatch ;
214
+ }
215
+
208
216
struct Allocator {
209
217
static const uptr kMaxAllowedMallocSize =
210
218
FIRST_32_SECOND_64 (3UL << 30 , 64UL << 30 );
@@ -217,19 +225,42 @@ struct Allocator {
217
225
AllocatorCache fallback_allocator_cache;
218
226
QuarantineCache fallback_quarantine_cache;
219
227
228
+ // ------------------- Options --------------------------
229
+ atomic_uint16_t min_redzone;
230
+ atomic_uint16_t max_redzone;
231
+ atomic_uint8_t alloc_dealloc_mismatch;
232
+
233
+ // ------------------- Initialization ------------------------
220
234
explicit Allocator (LinkerInitialized)
221
235
: quarantine(LINKER_INITIALIZED),
222
236
fallback_quarantine_cache(LINKER_INITIALIZED) {}
223
237
224
- // ------------------- Initialization ------------------------
225
- void Initialize (bool may_return_null, uptr quarantine_size) {
226
- allocator.Init (may_return_null);
227
- quarantine.Init (quarantine_size, kMaxThreadLocalQuarantine );
238
+ void CheckOptions (const AllocatorOptions &options) const {
239
+ CHECK_GE (options.min_redzone , 16 );
240
+ CHECK_GE (options.max_redzone , options.min_redzone );
241
+ CHECK_LE (options.max_redzone , 2048 );
242
+ CHECK (IsPowerOfTwo (options.min_redzone ));
243
+ CHECK (IsPowerOfTwo (options.max_redzone ));
228
244
}
229
245
230
- void ReInitialize (bool may_return_null, uptr quarantine_size) {
231
- allocator.SetMayReturnNull (may_return_null);
232
- quarantine.Init (quarantine_size, kMaxThreadLocalQuarantine );
246
+ void SharedInitCode (const AllocatorOptions &options) {
247
+ CheckOptions (options);
248
+ quarantine.Init ((uptr)options.quarantine_size_mb << 20 ,
249
+ kMaxThreadLocalQuarantine );
250
+ atomic_store (&alloc_dealloc_mismatch, options.alloc_dealloc_mismatch ,
251
+ memory_order_release);
252
+ atomic_store (&min_redzone, options.min_redzone , memory_order_release);
253
+ atomic_store (&max_redzone, options.max_redzone , memory_order_release);
254
+ }
255
+
256
+ void Initialize (const AllocatorOptions &options) {
257
+ allocator.Init (options.may_return_null );
258
+ SharedInitCode (options);
259
+ }
260
+
261
+ void ReInitialize (const AllocatorOptions &options) {
262
+ allocator.SetMayReturnNull (options.may_return_null );
263
+ SharedInitCode (options);
233
264
}
234
265
235
266
// -------------------- Helper methods. -------------------------
@@ -242,8 +273,9 @@ struct Allocator {
242
273
user_requested_size <= (1 << 14 ) - 256 ? 4 :
243
274
user_requested_size <= (1 << 15 ) - 512 ? 5 :
244
275
user_requested_size <= (1 << 16 ) - 1024 ? 6 : 7 ;
245
- return Min (Max (rz_log, RZSize2Log (flags ()->redzone )),
246
- RZSize2Log (flags ()->max_redzone ));
276
+ u32 min_rz = atomic_load (&min_redzone, memory_order_acquire);
277
+ u32 max_rz = atomic_load (&max_redzone, memory_order_acquire);
278
+ return Min (Max (rz_log, RZSize2Log (min_rz)), RZSize2Log (max_rz));
247
279
}
248
280
249
281
// We have an address between two chunks, and we want to report just one.
@@ -419,9 +451,12 @@ struct Allocator {
419
451
AllocType alloc_type) {
420
452
CHECK_EQ (m->chunk_state , CHUNK_QUARANTINE);
421
453
422
- if (m->alloc_type != alloc_type && flags ()->alloc_dealloc_mismatch )
423
- ReportAllocTypeMismatch ((uptr)ptr, stack,
424
- (AllocType)m->alloc_type , (AllocType)alloc_type);
454
+ if (m->alloc_type != alloc_type) {
455
+ if (atomic_load (&alloc_dealloc_mismatch, memory_order_acquire)) {
456
+ ReportAllocTypeMismatch ((uptr)ptr, stack, (AllocType)m->alloc_type ,
457
+ (AllocType)alloc_type);
458
+ }
459
+ }
425
460
426
461
CHECK_GE (m->alloc_tid , 0 );
427
462
if (SANITIZER_WORDSIZE == 64 ) // On 32-bits this resides in user area.
@@ -619,12 +654,12 @@ StackTrace AsanChunkView::GetFreeStack() {
619
654
return GetStackTraceFromId (chunk_->free_context_id );
620
655
}
621
656
622
- void InitializeAllocator (bool may_return_null, uptr quarantine_size ) {
623
- instance.Initialize (may_return_null, quarantine_size );
657
+ void InitializeAllocator (const AllocatorOptions &options ) {
658
+ instance.Initialize (options );
624
659
}
625
660
626
- void ReInitializeAllocator (bool may_return_null, uptr quarantine_size ) {
627
- instance.ReInitialize (may_return_null, quarantine_size );
661
+ void ReInitializeAllocator (const AllocatorOptions &options ) {
662
+ instance.ReInitialize (options );
628
663
}
629
664
630
665
AsanChunkView FindHeapChunkByAddress (uptr addr) {
0 commit comments