[compiler-rt] Ensure that reallocate copies everything (PR #189724)
Sadaf Ebrahimi via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 08:22:35 PDT 2026
https://github.com/sadafebrahimi updated https://github.com/llvm/llvm-project/pull/189724
>From 68e6cc5d622d4332c649faec56cec0caaece8ee7 Mon Sep 17 00:00:00 2001
From: Sadaf Ebrahimi <sadafebrahimi at google.com>
Date: Wed, 1 Apr 2026 15:21:26 +0000
Subject: [PATCH] [scudo] Ensure that reallocate copies everything
getUsableSize returns the actual capacity of the underlying block, which
may be larger than the size originally requested by the user. If the
user writes data into this extra space accessible via getUsableSize and
subsequently calls reallocate, the existing implementation only copies
the original requested number of bytes. This resulted in data loss for
any information stored beyond the requested size but within the usable
bounds.
---
compiler-rt/lib/scudo/standalone/combined.h | 5 +---
.../scudo/standalone/tests/combined_test.cpp | 24 +++++++++++++++++++
2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h
index 99f9ae99064e3..61f45a0089727 100644
--- a/compiler-rt/lib/scudo/standalone/combined.h
+++ b/compiler-rt/lib/scudo/standalone/combined.h
@@ -614,16 +614,13 @@ class Allocator {
void *BlockBegin = getBlockBegin(OldTaggedPtr, &Header);
uptr BlockEnd;
- uptr OldSize;
+ uptr OldSize = getUsableSize(OldTaggedPtr, &Header);
const uptr ClassId = Header.ClassId;
if (LIKELY(ClassId)) {
BlockEnd = reinterpret_cast<uptr>(BlockBegin) +
SizeClassMap::getSizeByClassId(ClassId);
- OldSize = Header.SizeOrUnusedBytes;
} else {
BlockEnd = SecondaryT::getBlockEnd(BlockBegin);
- OldSize = BlockEnd - (reinterpret_cast<uptr>(OldTaggedPtr) +
- Header.SizeOrUnusedBytes);
}
// If the new chunk still fits in the previously allocated block (with a
// reasonable delta), we just keep the old block, and update the chunk
diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
index 45616a3946dc7..268fea81feca7 100644
--- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
@@ -1471,6 +1471,30 @@ TEST(ScudoCombinedTest, FullUsableSize) {
VerifyIterateOverUsableSize<AllocatorT>(*Allocator);
}
+TEST(ScudoCombinedTest, ReallocUsableSize) {
+ using AllocatorT = TestAllocator<TestFullUsableSizeConfig>;
+ auto Allocator = std::unique_ptr<AllocatorT>(new AllocatorT());
+
+ scudo::uptr Size = 1000;
+ void *P = Allocator->allocate(Size, Origin);
+ scudo::uptr UsableSize = Allocator->getUsableSize(P);
+ std::vector<unsigned char> Buffer(UsableSize);
+ for (size_t I = 0; I < UsableSize; I++) {
+ Buffer[I] = I & 0xff;
+ }
+ memcpy(P, Buffer.data(), UsableSize);
+ EXPECT_LE(Size, UsableSize);
+
+ scudo::uptr NewSize = 2 * UsableSize;
+ void *NewP = Allocator->reallocate(P, NewSize);
+ EXPECT_NE(NewP, P);
+ for (size_t I = 0; I < UsableSize; I++) {
+ EXPECT_EQ((reinterpret_cast<unsigned char *>(NewP))[I], I & 0xff)
+ << "Failed at index " << I;
+ }
+ Allocator->deallocate(NewP, Origin);
+}
+
struct TestFullUsableSizeMTEConfig : TestFullUsableSizeConfig {
static const bool MaySupportMemoryTagging = true;
};
More information about the llvm-commits
mailing list