diff options
author | Fabio D'Urso <fdurso@google.com> | 2024-06-19 09:37:23 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-19 09:37:23 +0200 |
commit | 7fc975aa26f2e0ce6c80629209115ea58b245da5 (patch) | |
tree | 47303613672d8e61655eef6c61436b2b9bb0f7f7 | |
parent | 519175c3f5d844bac0cf3173396dc41db2873e1d (diff) | |
download | llvm-7fc975aa26f2e0ce6c80629209115ea58b245da5.zip llvm-7fc975aa26f2e0ce6c80629209115ea58b245da5.tar.gz llvm-7fc975aa26f2e0ce6c80629209115ea58b245da5.tar.bz2 |
Reland "[scudo] Apply filling when realloc shrinks and re-grows a block in-place" (#95838)
Reland of #93212, which had been reverted in
commit bddd8eae17df6511aee789744ccdc158de817081.
-rw-r--r-- | compiler-rt/lib/scudo/standalone/combined.h | 13 | ||||
-rw-r--r-- | compiler-rt/lib/scudo/standalone/tests/combined_test.cpp | 23 |
2 files changed, 31 insertions, 5 deletions
diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h index f9ed365..fcf6565 100644 --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -549,6 +549,19 @@ public: // header to reflect the size change. if (reinterpret_cast<uptr>(OldTaggedPtr) + NewSize <= BlockEnd) { if (NewSize > OldSize || (OldSize - NewSize) < getPageSizeCached()) { + // If we have reduced the size, set the extra bytes to the fill value + // so that we are ready to grow it again in the future. + if (NewSize < OldSize) { + const FillContentsMode FillContents = + TSDRegistry.getDisableMemInit() ? NoFill + : Options.getFillContentsMode(); + if (FillContents != NoFill) { + memset(reinterpret_cast<char *>(OldTaggedPtr) + NewSize, + FillContents == ZeroFill ? 0 : PatternFillByte, + OldSize - NewSize); + } + } + Header.SizeOrUnusedBytes = (ClassId ? NewSize : BlockEnd - diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp index 1a36155..16b19e8 100644 --- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp @@ -447,19 +447,32 @@ SCUDO_TYPED_TEST(ScudoCombinedDeathTest, ReallocateSame) { // returns the same chunk. This requires that all the sizes we iterate on use // the same block size, but that should be the case for MaxSize - 64 with our // default class size maps. - constexpr scudo::uptr ReallocSize = + constexpr scudo::uptr InitialSize = TypeParam::Primary::SizeClassMap::MaxSize - 64; - void *P = Allocator->allocate(ReallocSize, Origin); const char Marker = 'A'; - memset(P, Marker, ReallocSize); + Allocator->setFillContents(scudo::PatternOrZeroFill); + + void *P = Allocator->allocate(InitialSize, Origin); + scudo::uptr CurrentSize = InitialSize; for (scudo::sptr Delta = -32; Delta < 32; Delta += 8) { + memset(P, Marker, CurrentSize); const scudo::uptr NewSize = - static_cast<scudo::uptr>(static_cast<scudo::sptr>(ReallocSize) + Delta); + static_cast<scudo::uptr>(static_cast<scudo::sptr>(InitialSize) + Delta); void *NewP = Allocator->reallocate(P, NewSize); EXPECT_EQ(NewP, P); - for (scudo::uptr I = 0; I < ReallocSize - 32; I++) + + // Verify that existing contents have been preserved. + for (scudo::uptr I = 0; I < scudo::Min(CurrentSize, NewSize); I++) EXPECT_EQ((reinterpret_cast<char *>(NewP))[I], Marker); + + // Verify that new bytes are set according to FillContentsMode. + for (scudo::uptr I = CurrentSize; I < NewSize; I++) { + unsigned char V = (reinterpret_cast<unsigned char *>(NewP))[I]; + EXPECT_TRUE(V == scudo::PatternFillByte || V == 0); + } + checkMemoryTaggingMaybe(Allocator, NewP, NewSize, 0); + CurrentSize = NewSize; } Allocator->deallocate(P, Origin); } |