[PATCH] D70908: [scudo][standalone] Add chunk ownership function
Kostya Kortchinsky via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 2 08:52:55 PST 2019
cryptoad created this revision.
cryptoad added reviewers: hctim, pcc, cferris, eugenis, vitalybuka.
Herald added subscribers: Sanitizers, jfb, JDevlieghere.
Herald added projects: Sanitizers, LLVM.
In order to be compliant with tcmalloc's extension ownership
determination function, we have to expose a function that will
say if a chunk was allocated by us.
As to whether or not this has security consequences: someone
able to call this function repeatedly could use it to determine
secrets (cookie) or craft a valid header. So this should not be
exposed directly to untrusted user input.
Add related tests.
Additionally clang-format caught a few things to change.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D70908
Files:
compiler-rt/lib/scudo/standalone/chunk.h
compiler-rt/lib/scudo/standalone/combined.h
compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
Index: compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
===================================================================
--- compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
+++ compiler-rt/lib/scudo/standalone/tests/combined_test.cpp
@@ -32,6 +32,12 @@
Deleter);
Allocator->reset();
+ EXPECT_FALSE(Allocator->isOwned(&Mutex));
+ EXPECT_FALSE(Allocator->isOwned(&Allocator));
+ scudo::u64 StackVariable = 0x42424242U;
+ EXPECT_FALSE(Allocator->isOwned(&StackVariable));
+ EXPECT_EQ(StackVariable, 0x42424242U);
+
constexpr scudo::uptr MinAlignLog = FIRST_32_SECOND_64(3U, 4U);
// This allocates and deallocates a bunch of chunks, with a wide range of
@@ -46,6 +52,7 @@
const scudo::uptr Size = (1U << SizeLog) + Delta;
void *P = Allocator->allocate(Size, Origin, Align);
EXPECT_NE(P, nullptr);
+ EXPECT_TRUE(Allocator->isOwned(P));
EXPECT_TRUE(scudo::isAligned(reinterpret_cast<scudo::uptr>(P), Align));
EXPECT_LE(Size, Allocator->getUsableSize(P));
memset(P, 0xaa, Size);
Index: compiler-rt/lib/scudo/standalone/combined.h
===================================================================
--- compiler-rt/lib/scudo/standalone/combined.h
+++ compiler-rt/lib/scudo/standalone/combined.h
@@ -457,6 +457,17 @@
Stats.get(S);
}
+ // Returns true if the pointer provided was allocated by the current
+ // allocator instance, which is compliant with tcmalloc's ownership concept.
+ bool isOwned(const void *Ptr) {
+ initThreadMaybe();
+ if (!Ptr || !isAligned(reinterpret_cast<uptr>(Ptr), MinAlignment))
+ return false;
+ Chunk::UnpackedHeader Header;
+ return Chunk::isValid(Cookie, Ptr, &Header) &&
+ Header.State == Chunk::State::Allocated;
+ }
+
private:
using SecondaryT = typename Params::Secondary;
typedef typename PrimaryT::SizeClassMap SizeClassMap;
@@ -468,6 +479,8 @@
static const uptr MaxAllowedMallocSize =
FIRST_32_SECOND_64(1UL << 31, 1ULL << 40);
+ static_assert(MinAlignment >= sizeof(Chunk::PackedHeader), "");
+
// Constants used by the chunk iteration mechanism.
static const u32 BlockMarker = 0x44554353U;
static const uptr InvalidChunk = ~static_cast<uptr>(0);
Index: compiler-rt/lib/scudo/standalone/chunk.h
===================================================================
--- compiler-rt/lib/scudo/standalone/chunk.h
+++ compiler-rt/lib/scudo/standalone/chunk.h
@@ -91,8 +91,7 @@
getHeaderSize());
}
-inline
-const AtomicPackedHeader *getConstAtomicHeader(const void *Ptr) {
+inline const AtomicPackedHeader *getConstAtomicHeader(const void *Ptr) {
return reinterpret_cast<const AtomicPackedHeader *>(
reinterpret_cast<uptr>(Ptr) - getHeaderSize());
}
@@ -118,9 +117,8 @@
atomic_store_relaxed(getAtomicHeader(Ptr), NewPackedHeader);
}
-inline
-void loadHeader(u32 Cookie, const void *Ptr,
- UnpackedHeader *NewUnpackedHeader) {
+inline void loadHeader(u32 Cookie, const void *Ptr,
+ UnpackedHeader *NewUnpackedHeader) {
PackedHeader NewPackedHeader = atomic_load_relaxed(getConstAtomicHeader(Ptr));
*NewUnpackedHeader = bit_cast<UnpackedHeader>(NewPackedHeader);
if (UNLIKELY(NewUnpackedHeader->Checksum !=
@@ -141,8 +139,8 @@
reportHeaderRace(Ptr);
}
-inline
-bool isValid(u32 Cookie, const void *Ptr, UnpackedHeader *NewUnpackedHeader) {
+inline bool isValid(u32 Cookie, const void *Ptr,
+ UnpackedHeader *NewUnpackedHeader) {
PackedHeader NewPackedHeader = atomic_load_relaxed(getConstAtomicHeader(Ptr));
*NewUnpackedHeader = bit_cast<UnpackedHeader>(NewPackedHeader);
return NewUnpackedHeader->Checksum ==
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70908.231721.patch
Type: text/x-patch
Size: 3812 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191202/04201565/attachment.bin>
More information about the llvm-commits
mailing list