Skip to content

Commit 760d880

Browse files
authored
[scudo] Apply filling when realloc shrinks and re-grows a block in-place (#93212)
1 parent 38c01c3 commit 760d880

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

compiler-rt/lib/scudo/standalone/combined.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,20 @@ class Allocator {
565565
storeSecondaryAllocationStackMaybe(Options, OldPtr, NewSize);
566566
}
567567
}
568+
569+
// If we have reduced the size, set the extra bytes to the fill value
570+
// so that we are ready to grow it again in the future.
571+
if (NewSize < OldSize) {
572+
const FillContentsMode FillContents =
573+
TSDRegistry.getDisableMemInit() ? NoFill
574+
: Options.getFillContentsMode();
575+
if (FillContents != NoFill) {
576+
memset(reinterpret_cast<char *>(OldTaggedPtr) + NewSize,
577+
FillContents == ZeroFill ? 0 : PatternFillByte,
578+
OldSize - NewSize);
579+
}
580+
}
581+
568582
return OldTaggedPtr;
569583
}
570584
}

compiler-rt/lib/scudo/standalone/tests/combined_test.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -447,19 +447,32 @@ SCUDO_TYPED_TEST(ScudoCombinedDeathTest, ReallocateSame) {
447447
// returns the same chunk. This requires that all the sizes we iterate on use
448448
// the same block size, but that should be the case for MaxSize - 64 with our
449449
// default class size maps.
450-
constexpr scudo::uptr ReallocSize =
450+
constexpr scudo::uptr InitialSize =
451451
TypeParam::Primary::SizeClassMap::MaxSize - 64;
452-
void *P = Allocator->allocate(ReallocSize, Origin);
453452
const char Marker = 'A';
454-
memset(P, Marker, ReallocSize);
453+
Allocator->setFillContents(scudo::PatternOrZeroFill);
454+
455+
void *P = Allocator->allocate(InitialSize, Origin);
456+
scudo::uptr CurrentSize = InitialSize;
455457
for (scudo::sptr Delta = -32; Delta < 32; Delta += 8) {
458+
memset(P, Marker, CurrentSize);
456459
const scudo::uptr NewSize =
457-
static_cast<scudo::uptr>(static_cast<scudo::sptr>(ReallocSize) + Delta);
460+
static_cast<scudo::uptr>(static_cast<scudo::sptr>(InitialSize) + Delta);
458461
void *NewP = Allocator->reallocate(P, NewSize);
459462
EXPECT_EQ(NewP, P);
460-
for (scudo::uptr I = 0; I < ReallocSize - 32; I++)
463+
464+
// Verify that existing contents have been preserved.
465+
for (scudo::uptr I = 0; I < scudo::Min(CurrentSize, NewSize); I++)
461466
EXPECT_EQ((reinterpret_cast<char *>(NewP))[I], Marker);
467+
468+
// Verify that new bytes are set according to FillContentsMode.
469+
for (scudo::uptr I = CurrentSize; I < NewSize; I++) {
470+
EXPECT_EQ((reinterpret_cast<unsigned char *>(NewP))[I],
471+
scudo::PatternFillByte);
472+
}
473+
462474
checkMemoryTaggingMaybe(Allocator, NewP, NewSize, 0);
475+
CurrentSize = NewSize;
463476
}
464477
Allocator->deallocate(P, Origin);
465478
}

0 commit comments

Comments
 (0)