1 // Copyright 2021 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef PARTITION_ALLOC_SHIM_NONSCANNABLE_ALLOCATOR_H_ 6 #define PARTITION_ALLOC_SHIM_NONSCANNABLE_ALLOCATOR_H_ 7 8 #include <atomic> 9 #include <cstddef> 10 #include <memory> 11 12 #include "partition_alloc/partition_alloc_base/component_export.h" 13 #include "partition_alloc/partition_alloc_base/export_template.h" 14 #include "partition_alloc/partition_alloc_base/no_destructor.h" 15 #include "partition_alloc/partition_alloc_buildflags.h" 16 17 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) 18 #include "partition_alloc/partition_alloc.h" 19 20 #if BUILDFLAG(USE_STARSCAN) 21 #include "partition_alloc/internal_allocator_forward.h" 22 #endif 23 #endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) 24 25 namespace allocator_shim { 26 27 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) 28 namespace internal { 29 30 // Represents allocator that contains memory for data-like objects (that don't 31 // contain pointers/references) and therefore doesn't require scanning by 32 // PCScan. An example would be strings or socket/IPC/file buffers. Use with 33 // caution. 34 template <bool quarantinable> 35 class NonScannableAllocatorImpl final { 36 public: 37 static NonScannableAllocatorImpl& Instance(); 38 39 NonScannableAllocatorImpl(const NonScannableAllocatorImpl&) = delete; 40 NonScannableAllocatorImpl& operator=(const NonScannableAllocatorImpl&) = 41 delete; 42 43 void* Alloc(size_t size); 44 void Free(void*); 45 46 // Returns PartitionRoot corresponding to the allocator, or nullptr if the 47 // allocator is not enabled. root()48 partition_alloc::PartitionRoot* root() { 49 #if BUILDFLAG(USE_STARSCAN) 50 if (!allocator_.get()) { 51 return nullptr; 52 } 53 return allocator_->root(); 54 #else 55 return nullptr; 56 #endif // BUILDFLAG(USE_STARSCAN) 57 } 58 59 void NotifyPCScanEnabled(); 60 61 private: 62 template <typename> 63 friend class partition_alloc::internal::base::NoDestructor; 64 65 NonScannableAllocatorImpl(); 66 ~NonScannableAllocatorImpl(); 67 68 #if BUILDFLAG(USE_STARSCAN) 69 std::unique_ptr<partition_alloc::PartitionAllocator, 70 partition_alloc::internal::InternalPartitionDeleter> 71 allocator_; 72 std::atomic_bool pcscan_enabled_{false}; 73 #endif // BUILDFLAG(USE_STARSCAN) 74 }; 75 76 extern template class PA_EXPORT_TEMPLATE_DECLARE( 77 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM)) NonScannableAllocatorImpl<true>; 78 extern template class PA_EXPORT_TEMPLATE_DECLARE( 79 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM)) NonScannableAllocatorImpl<false>; 80 81 } // namespace internal 82 83 using NonScannableAllocator = internal::NonScannableAllocatorImpl<true>; 84 using NonQuarantinableAllocator = internal::NonScannableAllocatorImpl<false>; 85 86 #endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) 87 88 } // namespace allocator_shim 89 90 #endif // PARTITION_ALLOC_SHIM_NONSCANNABLE_ALLOCATOR_H_ 91