[compiler-rt] Double free (PR #110345)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 27 17:18:45 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Christopher Ferris (cferris1000)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/110345.diff
2 Files Affected:
- (modified) compiler-rt/lib/scudo/standalone/combined.h (+14-9)
- (modified) compiler-rt/lib/scudo/standalone/tests/combined_test.cpp (+21)
``````````diff
diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h
index a5f1bc388e8824..2e6867c6bafcb0 100644
--- a/compiler-rt/lib/scudo/standalone/combined.h
+++ b/compiler-rt/lib/scudo/standalone/combined.h
@@ -1252,22 +1252,25 @@ class Allocator {
else
Header->State = Chunk::State::Quarantined;
- void *BlockBegin;
- if (LIKELY(!useMemoryTagging<AllocatorConfig>(Options))) {
+ if (LIKELY(!useMemoryTagging<AllocatorConfig>(Options)))
Header->OriginOrWasZeroed = 0U;
- if (BypassQuarantine && allocatorSupportsMemoryTagging<AllocatorConfig>())
- Ptr = untagPointer(Ptr);
- BlockBegin = getBlockBegin(Ptr, Header);
- } else {
+ else
Header->OriginOrWasZeroed =
Header->ClassId && !TSDRegistry.getDisableMemInit();
- BlockBegin =
- retagBlock(Options, TaggedPtr, Ptr, Header, Size, BypassQuarantine);
- }
Chunk::storeHeader(Cookie, Ptr, Header);
if (BypassQuarantine) {
+ void *BlockBegin;
+ if (LIKELY(!useMemoryTagging<AllocatorConfig>(Options))) {
+ // Must do this after storeHeader because loadHeader uses a tagged ptr.
+ if (allocatorSupportsMemoryTagging<AllocatorConfig>())
+ Ptr = untagPointer(Ptr);
+ BlockBegin = getBlockBegin(Ptr, Header);
+ } else {
+ BlockBegin = retagBlock(Options, TaggedPtr, Ptr, Header, Size, true);
+ }
+
const uptr ClassId = Header->ClassId;
if (LIKELY(ClassId)) {
bool CacheDrained;
@@ -1285,6 +1288,8 @@ class Allocator {
Secondary.deallocate(Options, BlockBegin);
}
} else {
+ if (UNLIKELY(useMemoryTagging<AllocatorConfig>(Options)))
+ retagBlock(Options, TaggedPtr, Ptr, Header, Size, false);
typename TSDRegistryT::ScopedTSD TSD(TSDRegistry);
Quarantine.put(&TSD->getQuarantineCache(),
QuarantineCallback(*this, TSD->getCache()), Ptr, Size);
diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
index 16b19e807e11bc..ff98eb3397ee0e 100644
--- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
@@ -534,6 +534,27 @@ SCUDO_TYPED_TEST(ScudoCombinedDeathTest, UseAfterFree) {
}
}
+SCUDO_TYPED_TEST(ScudoCombinedDeathTest, DoubleFreeFromPrimary) {
+ auto *Allocator = this->Allocator.get();
+
+ for (scudo::uptr SizeLog = 0U; SizeLog <= 20U; SizeLog++) {
+ const scudo::uptr Size = 1U << SizeLog;
+ if (!isPrimaryAllocation<TestAllocator<TypeParam>>(Size, 0))
+ break;
+
+ // Verify that a double free results in a chunk state error.
+ EXPECT_DEATH(
+ {
+ // Allocate from primary
+ void *P = Allocator->allocate(Size, Origin);
+ ASSERT_TRUE(P != nullptr);
+ Allocator->deallocate(P, Origin);
+ Allocator->deallocate(P, Origin);
+ },
+ "invalid chunk state");
+ }
+}
+
SCUDO_TYPED_TEST(ScudoCombinedDeathTest, DisableMemoryTagging) {
auto *Allocator = this->Allocator.get();
``````````
</details>
https://github.com/llvm/llvm-project/pull/110345
More information about the llvm-commits
mailing list