Oilpan: Add magic number to BasePage
Adds magic number to BasePage and use it to validate page in PageFromObject().
Bug:
Change-Id: I298588e1c61ec49a878a3b02f29650156bbc02e3
Reviewed-on: https://chromium-review.googlesource.com/756716
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Keishi Hattori <keishi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#516149}
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
index 40eed16..2e239ae 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -1266,7 +1266,8 @@
}
BasePage::BasePage(PageMemory* storage, BaseArena* arena)
- : storage_(storage),
+ : magic_(GetMagic()),
+ storage_(storage),
arena_(arena),
next_(nullptr),
swept_(true),
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.h b/third_party/WebKit/Source/platform/heap/HeapPage.h
index a8933accf..02ef15a 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.h
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.h
@@ -135,6 +135,16 @@
class PageMemory;
class BaseArena;
+// Returns a random value.
+//
+// The implementation gets its randomness from the locations of 2 independent
+// sources of address space layout randomization: a function in a Chrome
+// executable image, and a function in an external DLL/so. This implementation
+// should be fast and small, and should have the benefit of requiring
+// attackers to discover and use 2 independent weak infoleak bugs, or 1
+// arbitrary infoleak bug (used twice).
+inline uint32_t GetRandomMagic();
+
// HeapObjectHeader is a 64-bit (64-bit platforms) or 32-bit (32-bit platforms)
// object that has the following layout:
//
@@ -271,15 +281,8 @@
void CheckHeader() const;
#if defined(ARCH_CPU_64_BITS)
- // Returns a random value.
- //
- // The implementation gets its randomness from the locations of 2 independent
- // sources of address space layout randomization: a function in a Chrome
- // executable image, and a function in an external DLL/so. This implementation
- // should be fast and small, and should have the benefit of requiring
- // attackers to discover and use 2 independent weak infoleak bugs, or 1
- // arbitrary infoleak bug (used twice).
- uint32_t GetMagic() const;
+ // Returns a random magic value.
+ uint32_t GetMagic() const { return GetRandomMagic() ^ 0x6e0b6ead; }
uint32_t magic_;
#endif // defined(ARCH_CPU_64_BITS)
@@ -464,9 +467,16 @@
bool IsIncrementalMarking() const { return incremental_marking_; }
+ // Returns true if magic number is valid.
+ bool IsValid() const;
+
private:
- PageMemory* storage_;
- BaseArena* arena_;
+ // Returns a random magic value.
+ uint32_t GetMagic() const { return GetRandomMagic() ^ 0xba5e4a9e; }
+
+ uint32_t const magic_;
+ PageMemory* const storage_;
+ BaseArena* const arena_;
BasePage* next_;
// Track the sweeping state of a page. Set to false at the start of a sweep,
@@ -878,6 +888,7 @@
Address address = reinterpret_cast<Address>(const_cast<void*>(object));
BasePage* page = reinterpret_cast<BasePage*>(BlinkPageAddress(address) +
kBlinkGuardPageSize);
+ CHECK(page->IsValid());
#if DCHECK_IS_ON()
DCHECK(page->Contains(address));
#endif
@@ -947,7 +958,6 @@
(void)FromPayload(payload);
}
-#if defined(ARCH_CPU_64_BITS)
ALWAYS_INLINE uint32_t RotateLeft16(uint32_t x) {
#if defined(COMPILER_MSVC)
return _lrotr(x, 16);
@@ -957,7 +967,7 @@
#endif
}
-inline uint32_t HeapObjectHeader::GetMagic() const {
+inline uint32_t GetRandomMagic() {
// Ignore C4319: It is OK to 0-extend into the high-order bits of the uintptr_t
// on 64-bit, in this case.
#if defined(COMPILER_MSVC)
@@ -999,7 +1009,6 @@
return random;
}
-#endif // defined(ARCH_CPU_64_BITS)
NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsWrapperHeaderMarked()
const {
@@ -1036,6 +1045,10 @@
encoded_ &= ~kHeaderMarkBitMask;
}
+NO_SANITIZE_ADDRESS inline bool BasePage::IsValid() const {
+ return GetMagic() == magic_;
+}
+
inline Address NormalPageArena::AllocateObject(size_t allocation_size,
size_t gc_info_index) {
if (LIKELY(allocation_size <= remaining_allocation_size_)) {