[compiler-rt] 8fac07a - scudo: Exclude previous tag when retagging freed memory.
Peter Collingbourne via llvm-commits
llvm-commits at lists.llvm.org
Fri May 1 09:36:12 PDT 2020
Author: Peter Collingbourne
Date: 2020-05-01T09:35:38-07:00
New Revision: 8fac07a12adcd968cd4b6a1c1067e4596ad40b1a
URL: https://github.com/llvm/llvm-project/commit/8fac07a12adcd968cd4b6a1c1067e4596ad40b1a
DIFF: https://github.com/llvm/llvm-project/commit/8fac07a12adcd968cd4b6a1c1067e4596ad40b1a.diff
LOG: scudo: Exclude previous tag when retagging freed memory.
This means that immediate use after free will be detected 100% of
the time.
Differential Revision: https://reviews.llvm.org/D79216
Added:
Modified:
compiler-rt/lib/scudo/standalone/combined.h
compiler-rt/lib/scudo/standalone/memtag.h
Removed:
################################################################################
diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h
index 112aefdc3930..583b47a14258 100644
--- a/compiler-rt/lib/scudo/standalone/combined.h
+++ b/compiler-rt/lib/scudo/standalone/combined.h
@@ -983,7 +983,9 @@ class Allocator {
if (UNLIKELY(NewHeader.ClassId && useMemoryTagging())) {
u8 PrevTag = extractTag(loadTag(reinterpret_cast<uptr>(Ptr)));
uptr TaggedBegin, TaggedEnd;
- setRandomTag(Ptr, Size, &TaggedBegin, &TaggedEnd);
+ // Exclude the previous tag so that immediate use after free is detected
+ // 100% of the time.
+ setRandomTag(Ptr, Size, 1UL << PrevTag, &TaggedBegin, &TaggedEnd);
storeDeallocationStackMaybe(Ptr, PrevTag);
}
// If the quarantine is disabled, the actual size of a chunk is 0 or larger
diff --git a/compiler-rt/lib/scudo/standalone/memtag.h b/compiler-rt/lib/scudo/standalone/memtag.h
index 18dae2b8ca41..6f347f4694e8 100644
--- a/compiler-rt/lib/scudo/standalone/memtag.h
+++ b/compiler-rt/lib/scudo/standalone/memtag.h
@@ -93,8 +93,8 @@ class ScopedDisableMemoryTagChecks {
}
};
-inline void setRandomTag(void *Ptr, uptr Size, uptr *TaggedBegin,
- uptr *TaggedEnd) {
+inline void setRandomTag(void *Ptr, uptr Size, uptr ExcludeMask,
+ uptr *TaggedBegin, uptr *TaggedEnd) {
void *End;
__asm__ __volatile__(
R"(
@@ -102,7 +102,7 @@ inline void setRandomTag(void *Ptr, uptr Size, uptr *TaggedBegin,
// Set a random tag for Ptr in TaggedPtr. This needs to happen even if
// Size = 0 so that TaggedPtr ends up pointing at a valid address.
- irg %[TaggedPtr], %[Ptr]
+ irg %[TaggedPtr], %[Ptr], %[ExcludeMask]
mov %[Cur], %[TaggedPtr]
// Skip the loop if Size = 0. We don't want to do any tagging in this case.
@@ -120,9 +120,9 @@ inline void setRandomTag(void *Ptr, uptr Size, uptr *TaggedBegin,
2:
)"
- : [ TaggedPtr ] "=&r"(*TaggedBegin), [ Cur ] "=&r"(*TaggedEnd),
- [ End ] "=&r"(End)
- : [ Ptr ] "r"(Ptr), [ Size ] "r"(Size)
+ :
+ [TaggedPtr] "=&r"(*TaggedBegin), [Cur] "=&r"(*TaggedEnd), [End] "=&r"(End)
+ : [Ptr] "r"(Ptr), [Size] "r"(Size), [ExcludeMask] "r"(ExcludeMask)
: "memory");
}
@@ -138,7 +138,7 @@ inline void *prepareTaggedChunk(void *Ptr, uptr Size, uptr BlockEnd) {
: "memory");
uptr TaggedBegin, TaggedEnd;
- setRandomTag(Ptr, Size, &TaggedBegin, &TaggedEnd);
+ setRandomTag(Ptr, Size, 0, &TaggedBegin, &TaggedEnd);
// Finally, set the tag of the granule past the end of the allocation to 0,
// to catch linear overflows even if a previous larger allocation used the
@@ -225,10 +225,11 @@ struct ScopedDisableMemoryTagChecks {
ScopedDisableMemoryTagChecks() {}
};
-inline void setRandomTag(void *Ptr, uptr Size, uptr *TaggedBegin,
- uptr *TaggedEnd) {
+inline void setRandomTag(void *Ptr, uptr Size, uptr ExcludeMask,
+ uptr *TaggedBegin, uptr *TaggedEnd) {
(void)Ptr;
(void)Size;
+ (void)ExcludeMask;
(void)TaggedBegin;
(void)TaggedEnd;
UNREACHABLE("memory tagging not supported");
More information about the llvm-commits
mailing list