Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Unified Diff: sandbox/win/src/sandbox_nt_util_unittest.cc

Issue 2258583002: Reimplement AllocateNearTo for 64bit. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added unittests Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« sandbox/win/src/sandbox_nt_util.cc ('K') | « sandbox/win/src/sandbox_nt_util.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/win/src/sandbox_nt_util_unittest.cc
diff --git a/sandbox/win/src/sandbox_nt_util_unittest.cc b/sandbox/win/src/sandbox_nt_util_unittest.cc
index 0fbea6680247323a351574b8f9dfdb31f00c7685..863b584f2b9ec6b8a00e8c2b05d9dd921200c928 100644
--- a/sandbox/win/src/sandbox_nt_util_unittest.cc
+++ b/sandbox/win/src/sandbox_nt_util_unittest.cc
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <memory>
#include <windows.h>
+#include <vector>
#include "base/win/scoped_handle.h"
#include "base/win/scoped_process_information.h"
@@ -43,5 +45,141 @@ TEST(SandboxNtUtil, IsSameProcessDifferentProcess) {
EXPECT_TRUE(TerminateProcess(process_info.process_handle(), 0));
}
+#if defined(_WIN64)
+struct VirtualMemDeleter {
+ void operator()(char* p) { ::VirtualFree(p, 0, MEM_RELEASE); }
+};
+
+typedef std::unique_ptr<char, VirtualMemDeleter> unique_ptr_vmem;
+
+void AllocateBlock(SIZE_T size,
+ SIZE_T free_size,
+ char** base_address,
+ std::vector<unique_ptr_vmem>* mem_range) {
+ unique_ptr_vmem ptr(static_cast<char*>(::VirtualAlloc(
+ *base_address, size - free_size, MEM_RESERVE, PAGE_READWRITE)));
+ ASSERT_NE(nullptr, ptr.get());
+ mem_range->push_back(std::move(ptr));
+ *base_address += size;
+}
+
+#define KIB(x) ((x)*1024ULL)
+#define MIB(x) (KIB(x) * 1024ULL)
+#define GIB(x) (MIB(x) * 1024ULL)
+// Construct a basic memory layout to do the test. We reserve first to get a
+// base address then reallocate with the following pattern.
+// |512MiB-64KiB Free|512MiB-128Kib Free|512MiB-256Kib Free|512MiB+512KiB Free|
+void AllocateTestRange(std::vector<unique_ptr_vmem>* mem_range) {
+ // Ensure we preallocate enough space in the vector to prevent unexpected
+ // allocations.
+ mem_range->reserve(5);
+ SIZE_T total_size =
+ MIB(512) + MIB(512) + MIB(512) + MIB(512) + KIB(512) + KIB(64);
+ unique_ptr_vmem ptr(static_cast<char*>(
+ ::VirtualAlloc(nullptr, total_size, MEM_RESERVE, PAGE_READWRITE)));
+ ASSERT_NE(nullptr, ptr.get());
+ char* base_address = ptr.get();
+ char* orig_base = base_address;
+ ptr.reset();
+ AllocateBlock(MIB(512), KIB(64), &base_address, mem_range);
+ AllocateBlock(MIB(512), KIB(128), &base_address, mem_range);
+ AllocateBlock(MIB(512), KIB(256), &base_address, mem_range);
+ AllocateBlock(MIB(512) + KIB(512), KIB(512), &base_address, mem_range);
+ // Allocate a memory block at end to act as an upper bound.
+ AllocateBlock(KIB(64), 0, &base_address, mem_range);
+ ASSERT_EQ(total_size, static_cast<SIZE_T>(base_address - orig_base));
+}
+
+void TestAlignedRange(char* base_address) {
+ unique_ptr_vmem ptr_256k(new (sandbox::NT_PAGE, base_address) char[KIB(256)]);
+ EXPECT_EQ(base_address + GIB(1) + MIB(512) - KIB(256), ptr_256k.get());
+ unique_ptr_vmem ptr_64k(new (sandbox::NT_PAGE, base_address) char[KIB(64)]);
+ EXPECT_EQ(base_address + MIB(512) - KIB(64), ptr_64k.get());
+ unique_ptr_vmem ptr_128k(new (sandbox::NT_PAGE, base_address) char[KIB(128)]);
+ EXPECT_EQ(base_address + GIB(1) - KIB(128), ptr_128k.get());
+ // We will have run out of space here so should also fail.
+ unique_ptr_vmem ptr_64k_noalloc(
+ new (sandbox::NT_PAGE, base_address) char[KIB(64)]);
+ EXPECT_EQ(nullptr, ptr_64k_noalloc.get());
+}
+
+void Test512kBlock(char* base_address) {
+ // This should fail as it'll just be out of range.
+ unique_ptr_vmem ptr_512k_noalloc(
+ new (sandbox::NT_PAGE, base_address) char[KIB(512)]);
+ EXPECT_EQ(nullptr, ptr_512k_noalloc.get());
+ // Check that moving base address we can allocate the 512k block.
+ unique_ptr_vmem ptr_512k(
+ new (sandbox::NT_PAGE, base_address + GIB(1)) char[KIB(512)]);
+ EXPECT_EQ(base_address + GIB(2), ptr_512k.get());
+ // Free pointer first.
+ ptr_512k.reset();
+ ptr_512k.reset(new (sandbox::NT_PAGE, base_address + GIB(2)) char[KIB(512)]);
+ EXPECT_EQ(base_address + GIB(2), ptr_512k.get());
+}
+
+void TestUnalignedRange(char* base_address) {
+ char* unaligned_base = base_address + 123456;
+ unique_ptr_vmem ptr_256k(
+ new (sandbox::NT_PAGE, unaligned_base) char[KIB(256)]);
+ EXPECT_EQ(base_address + GIB(1) + MIB(512) - KIB(256), ptr_256k.get());
+ unique_ptr_vmem ptr_64k(new (sandbox::NT_PAGE, unaligned_base) char[KIB(64)]);
+ EXPECT_EQ(base_address + MIB(512) - KIB(64), ptr_64k.get());
+ unique_ptr_vmem ptr_128k(
+ new (sandbox::NT_PAGE, unaligned_base) char[KIB(128)]);
+ EXPECT_EQ(base_address + GIB(1) - KIB(128), ptr_128k.get());
+}
+
+void TestMaxAllocations(char* base_address) {
+ // There's only 7 64k blocks in the first 2g which we can fill.
+ unique_ptr_vmem ptr_1(new (sandbox::NT_PAGE, base_address) char[1]);
+ EXPECT_NE(nullptr, ptr_1.get());
+ unique_ptr_vmem ptr_2(new (sandbox::NT_PAGE, base_address) char[1]);
+ EXPECT_NE(nullptr, ptr_2.get());
+ unique_ptr_vmem ptr_3(new (sandbox::NT_PAGE, base_address) char[1]);
+ EXPECT_NE(nullptr, ptr_3.get());
+ unique_ptr_vmem ptr_4(new (sandbox::NT_PAGE, base_address) char[1]);
+ EXPECT_NE(nullptr, ptr_4.get());
+ unique_ptr_vmem ptr_5(new (sandbox::NT_PAGE, base_address) char[1]);
+ EXPECT_NE(nullptr, ptr_5.get());
+ unique_ptr_vmem ptr_6(new (sandbox::NT_PAGE, base_address) char[1]);
+ EXPECT_NE(nullptr, ptr_6.get());
+ unique_ptr_vmem ptr_7(new (sandbox::NT_PAGE, base_address) char[1]);
+ EXPECT_NE(nullptr, ptr_7.get());
+ unique_ptr_vmem ptr_8(new (sandbox::NT_PAGE, base_address) char[1]);
+ EXPECT_EQ(nullptr, ptr_8.get());
+}
+
+void TestExtremes() {
+ unique_ptr_vmem ptr_null(new (sandbox::NT_PAGE, nullptr) char[1]);
+ EXPECT_EQ(nullptr, ptr_null.get());
+ unique_ptr_vmem ptr_too_large(
+ new (sandbox::NT_PAGE, reinterpret_cast<void*>(0x1000000)) char[GIB(4)]);
+ EXPECT_EQ(nullptr, ptr_too_large.get());
+ unique_ptr_vmem ptr_overflow(
+ new (sandbox::NT_PAGE, reinterpret_cast<void*>(SIZE_MAX)) char[1]);
+ EXPECT_EQ(nullptr, ptr_overflow.get());
+ unique_ptr_vmem ptr_invalid(new (
+ sandbox::NT_PAGE, reinterpret_cast<void*>(SIZE_MAX - 0x1000000)) char[1]);
+ EXPECT_EQ(nullptr, ptr_invalid.get());
+}
+
+// Test nearest allocator, only do this for 64 bit.
Will Harris 2016/08/18 17:42:22 all these tests are ifdefed for 64-bit, can some r
+TEST(SandboxNtUtil, NearestAllocator) {
+ InitGlobalNt();
+ std::vector<unique_ptr_vmem> mem_range;
+ AllocateTestRange(&mem_range);
+ ASSERT_LT(0U, mem_range.size());
+ char* base_address = static_cast<char*>(mem_range[0].get());
+
+ TestAlignedRange(base_address);
+ Test512kBlock(base_address);
+ TestUnalignedRange(base_address);
+ TestMaxAllocations(base_address);
+ TestExtremes();
+}
+
+#endif // defined(_WIN64)
+
} // namespace
} // namespace sandbox
« sandbox/win/src/sandbox_nt_util.cc ('K') | « sandbox/win/src/sandbox_nt_util.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698