forked from OSchip/llvm-project
[scudo] Detect double free when running with MTE.
Try to trigger an MTE fault on double/invalid free by touching the first byte of the allocation with the provided pointer. Differential Revision: https://reviews.llvm.org/D137352
This commit is contained in:
parent
87debdadaf
commit
1dd54691b2
|
@ -560,7 +560,16 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to detect deallocation with a wrong MTE tag by touching the first
|
||||||
|
// byte with a correctly tagged pointer. Skip zero-sized allocations that do
|
||||||
|
// not always store the correct tag value anywhere (for example, a zero
|
||||||
|
// size, 32 byte aligned allocation in a 32-byte size class will end up with
|
||||||
|
// header at offset 16 in the block, payload at offset 32, and no space to
|
||||||
|
// store the tag).
|
||||||
const uptr Size = getSize(Ptr, &Header);
|
const uptr Size = getSize(Ptr, &Header);
|
||||||
|
if (useMemoryTagging<Params>(Options) && Size != 0)
|
||||||
|
*reinterpret_cast<volatile char *>(TaggedPtr);
|
||||||
|
|
||||||
if (DeleteSize && Options.get(OptionBit::DeleteSizeMismatch)) {
|
if (DeleteSize && Options.get(OptionBit::DeleteSizeMismatch)) {
|
||||||
if (UNLIKELY(DeleteSize != Size))
|
if (UNLIKELY(DeleteSize != Size))
|
||||||
reportDeleteSizeMismatch(Ptr, DeleteSize, Size);
|
reportDeleteSizeMismatch(Ptr, DeleteSize, Size);
|
||||||
|
|
|
@ -395,6 +395,27 @@ SCUDO_TYPED_TEST(ScudoCombinedDeathTest, UseAfterFree) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCUDO_TYPED_TEST(ScudoCombinedDeathTest, FreeWithTagMismatch) {
|
||||||
|
auto *Allocator = this->Allocator.get();
|
||||||
|
|
||||||
|
if (!Allocator->useMemoryTaggingTestOnly())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check that double free is detected.
|
||||||
|
for (scudo::uptr SizeLog = 0U; SizeLog <= 20U; SizeLog++) {
|
||||||
|
const scudo::uptr Size = 1U << SizeLog;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
disableDebuggerdMaybe();
|
||||||
|
void *P = Allocator->allocate(Size, Origin);
|
||||||
|
scudo::uptr NewTag = (scudo::extractTag(reinterpret_cast<scudo::uptr>(P)) + 1) % 16;
|
||||||
|
void *Q = scudo::addFixedTag(scudo::untagPointer(P), NewTag);
|
||||||
|
Allocator->deallocate(Q, Origin);
|
||||||
|
},
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SCUDO_TYPED_TEST(ScudoCombinedDeathTest, DisableMemoryTagging) {
|
SCUDO_TYPED_TEST(ScudoCombinedDeathTest, DisableMemoryTagging) {
|
||||||
auto *Allocator = this->Allocator.get();
|
auto *Allocator = this->Allocator.get();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue