Commit 5cc2dda5 authored by Bartek Nowierski's avatar Bartek Nowierski Committed by Commit Bot

Add a unittest that crashes on generation mismatch

Bug: 1073933
Change-Id: I52f561d908cd05b5e3406c0b252854779c1f927f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2269618
Auto-Submit: Bartek Nowierski <bartekn@chromium.org>
Commit-Queue: Kentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarŁukasz Anforowicz <lukasza@chromium.org>
Cr-Commit-Position: refs/heads/master@{#787582}
parent ddbc6e97
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include "base/allocator/partition_allocator/partition_alloc.h"
#include "base/allocator/partition_allocator/partition_cookie.h"
#include "base/allocator/partition_allocator/partition_tag.h" #include "base/allocator/partition_allocator/partition_tag.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -642,8 +644,11 @@ TEST(CheckedPtr2Impl, SafelyUnwrapNull) { ...@@ -642,8 +644,11 @@ TEST(CheckedPtr2Impl, SafelyUnwrapNull) {
} }
TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) { TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) {
// Put generation 16B and 32B before the "object", so that it works on both // Create a fake allocation, with first 32B for generation and optionally
// Debug and Release builds. // cookie for Debug builds (ignored), 16B each. Put generation both 16B and
// 32B before the "object", so that it works on both Debug and Release builds.
// We can use a fake allocation, instead of PartitionAlloc, because
// CheckedPtr2ImplEnabled fakes the functionality is enabled for this pointer.
char bytes[] = {0xBA, 0x42, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, char bytes[] = {0xBA, 0x42, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xBA, 0x42, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xBA, 0x42,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
...@@ -659,8 +664,8 @@ TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) { ...@@ -659,8 +664,8 @@ TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) {
#endif #endif
uintptr_t wrapped = CheckedPtr2ImplEnabled::WrapRawPtr(ptr); uintptr_t wrapped = CheckedPtr2ImplEnabled::WrapRawPtr(ptr);
// First 2 bytes in the preceding word will be used as generation (in reverse // First 2 bytes in the preceding 16B block will be used as generation (in
// order due to little-endianness). // reverse order due to little-endianness).
#if CHECKED_PTR2_USE_NO_OP_WRAPPER #if CHECKED_PTR2_USE_NO_OP_WRAPPER
ASSERT_EQ(wrapped, addr); ASSERT_EQ(wrapped, addr);
std::ignore = set_top_bit; std::ignore = set_top_bit;
...@@ -671,6 +676,7 @@ TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) { ...@@ -671,6 +676,7 @@ TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) {
ASSERT_EQ(CheckedPtr2ImplEnabled::SafelyUnwrapPtrForDereference(wrapped), ASSERT_EQ(CheckedPtr2ImplEnabled::SafelyUnwrapPtrForDereference(wrapped),
ptr); ptr);
// Modify the generation associated with the fake allocation.
bytes[1] |= 0x80; // for Debug builds bytes[1] |= 0x80; // for Debug builds
bytes[kCookieSize + 1] |= 0x80; // for Release builds bytes[kCookieSize + 1] |= 0x80; // for Release builds
wrapped = CheckedPtr2ImplEnabled::WrapRawPtr(ptr); wrapped = CheckedPtr2ImplEnabled::WrapRawPtr(ptr);
...@@ -683,6 +689,7 @@ TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) { ...@@ -683,6 +689,7 @@ TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) {
ptr); ptr);
#if CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING #if CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING
// Clear the generation associated with the fake allocation.
bytes[0] = 0; // for Debug builds bytes[0] = 0; // for Debug builds
bytes[1] = 0; bytes[1] = 0;
bytes[kCookieSize] = 0; // for Release builds bytes[kCookieSize] = 0; // for Release builds
...@@ -702,8 +709,11 @@ TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) { ...@@ -702,8 +709,11 @@ TEST(CheckedPtr2Impl, WrapAndSafelyUnwrap) {
} }
TEST(CheckedPtr2Impl, SafelyUnwrapDisabled) { TEST(CheckedPtr2Impl, SafelyUnwrapDisabled) {
// Put generation 16B and 32B before the "object", so that it works on both // Create a fake allocation, with first 32B for generation and optionally
// Debug and Release builds. // cookie for Debug builds (ignored), 16B each. Put generation both 16B and
// 32B before the "object", so that it works on both Debug and Release builds.
// We can use a fake allocation, instead of PartitionAlloc, because
// CheckedPtr2ImplEnabled fakes the functionality is enabled for this pointer.
char bytes[] = {0xBA, 0x42, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, char bytes[] = {0xBA, 0x42, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xBA, 0x42, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xBA, 0x42,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
...@@ -714,6 +724,28 @@ TEST(CheckedPtr2Impl, SafelyUnwrapDisabled) { ...@@ -714,6 +724,28 @@ TEST(CheckedPtr2Impl, SafelyUnwrapDisabled) {
ASSERT_EQ(CheckedPtr2ImplEnabled::SafelyUnwrapPtrForDereference(addr), ptr); ASSERT_EQ(CheckedPtr2ImplEnabled::SafelyUnwrapPtrForDereference(addr), ptr);
} }
TEST(CheckedPtr2Impl, CrashOnGenerationMismatch) {
// Create a fake allocation, with first 32B for generation and optionally
// cookie for Debug builds (ignored), 16B each. Put generation both 16B and
// 32B before the "object", so that it works on both Debug and Release builds.
// We can use a fake allocation, instead of PartitionAlloc, because
// CheckedPtr2ImplEnabled fakes the functionality is enabled for this pointer.
char bytes[] = {0xBA, 0x42, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xBA, 0x42,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x89};
CheckedPtr<char, CheckedPtr2ImplEnabled> ptr = bytes + 32;
EXPECT_TRUE(*ptr == 0x78);
// Clobber the generation associated with the fake allocation.
bytes[0] = 0; // for Debug builds
bytes[kCookieSize] = 0; // for Release builds
EXPECT_DEATH_IF_SUPPORTED(if (*ptr == 0x78) return, "");
}
void HandleOOM(size_t unused_size) {
LOG(FATAL) << "Out of memory";
}
} // namespace internal } // namespace internal
} // namespace base } // namespace base
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment