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

Side by Side 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: Better comments and used standard types 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 unified diff | Download patch
« no previous file with comments | « sandbox/win/src/sandbox_nt_util.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory>
5 #include <windows.h> 6 #include <windows.h>
7 #include <vector>
6 8
7 #include "base/win/scoped_handle.h" 9 #include "base/win/scoped_handle.h"
8 #include "base/win/scoped_process_information.h" 10 #include "base/win/scoped_process_information.h"
9 #include "sandbox/win/src/policy_broker.h" 11 #include "sandbox/win/src/policy_broker.h"
10 #include "sandbox/win/src/sandbox_nt_util.h" 12 #include "sandbox/win/src/sandbox_nt_util.h"
11 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
12 14
13 namespace sandbox { 15 namespace sandbox {
14 namespace { 16 namespace {
15 17
(...skipping 20 matching lines...) Expand all
36 PROCESS_INFORMATION pi = {}; 38 PROCESS_INFORMATION pi = {};
37 wchar_t notepad[] = L"notepad"; 39 wchar_t notepad[] = L"notepad";
38 ASSERT_TRUE(CreateProcessW(nullptr, notepad, nullptr, nullptr, FALSE, 0, 40 ASSERT_TRUE(CreateProcessW(nullptr, notepad, nullptr, nullptr, FALSE, 0,
39 nullptr, nullptr, &si, &pi)); 41 nullptr, nullptr, &si, &pi));
40 base::win::ScopedProcessInformation process_info(pi); 42 base::win::ScopedProcessInformation process_info(pi);
41 43
42 EXPECT_FALSE(IsSameProcess(process_info.process_handle())); 44 EXPECT_FALSE(IsSameProcess(process_info.process_handle()));
43 EXPECT_TRUE(TerminateProcess(process_info.process_handle(), 0)); 45 EXPECT_TRUE(TerminateProcess(process_info.process_handle(), 0));
44 } 46 }
45 47
48 #if defined(_WIN64)
49 struct VirtualMemDeleter {
50 void operator()(char* p) { ::VirtualFree(p, 0, MEM_RELEASE); }
51 };
52
53 typedef std::unique_ptr<char, VirtualMemDeleter> unique_ptr_vmem;
54
55 void AllocateBlock(SIZE_T size,
56 SIZE_T free_size,
57 char** base_address,
58 std::vector<unique_ptr_vmem>* mem_range) {
59 unique_ptr_vmem ptr(static_cast<char*>(::VirtualAlloc(
60 *base_address, size - free_size, MEM_RESERVE, PAGE_READWRITE)));
61 ASSERT_NE(nullptr, ptr.get());
62 mem_range->push_back(std::move(ptr));
63 *base_address += size;
64 }
65
66 #define KIB(x) ((x)*1024ULL)
67 #define MIB(x) (KIB(x) * 1024ULL)
68 #define GIB(x) (MIB(x) * 1024ULL)
69 // Construct a basic memory layout to do the test. We reserve first to get a
70 // base address then reallocate with the following pattern.
71 // |512MiB-64KiB Free|512MiB-128Kib Free|512MiB-256Kib Free|512MiB+512KiB Free|
72 // The purpose of this is leave a couple of free memory regions within a 2GiB
73 // block of reserved memory that we can test the searching allocator.
74 void AllocateTestRange(std::vector<unique_ptr_vmem>* mem_range) {
75 // Ensure we preallocate enough space in the vector to prevent unexpected
76 // allocations.
77 mem_range->reserve(5);
78 SIZE_T total_size =
79 MIB(512) + MIB(512) + MIB(512) + MIB(512) + KIB(512) + KIB(64);
80 unique_ptr_vmem ptr(static_cast<char*>(
81 ::VirtualAlloc(nullptr, total_size, MEM_RESERVE, PAGE_READWRITE)));
82 ASSERT_NE(nullptr, ptr.get());
83 char* base_address = ptr.get();
84 char* orig_base = base_address;
85 ptr.reset();
86 AllocateBlock(MIB(512), KIB(64), &base_address, mem_range);
87 AllocateBlock(MIB(512), KIB(128), &base_address, mem_range);
88 AllocateBlock(MIB(512), KIB(256), &base_address, mem_range);
89 AllocateBlock(MIB(512) + KIB(512), KIB(512), &base_address, mem_range);
90 // Allocate a memory block at end to act as an upper bound.
91 AllocateBlock(KIB(64), 0, &base_address, mem_range);
92 ASSERT_EQ(total_size, static_cast<SIZE_T>(base_address - orig_base));
93 }
94
95 // Test we can allocate appropriate blocks.
96 void TestAlignedRange(char* base_address) {
97 unique_ptr_vmem ptr_256k(new (sandbox::NT_PAGE, base_address) char[KIB(256)]);
98 EXPECT_EQ(base_address + GIB(1) + MIB(512) - KIB(256), ptr_256k.get());
99 unique_ptr_vmem ptr_64k(new (sandbox::NT_PAGE, base_address) char[KIB(64)]);
100 EXPECT_EQ(base_address + MIB(512) - KIB(64), ptr_64k.get());
101 unique_ptr_vmem ptr_128k(new (sandbox::NT_PAGE, base_address) char[KIB(128)]);
102 EXPECT_EQ(base_address + GIB(1) - KIB(128), ptr_128k.get());
103 // We will have run out of space here so should also fail.
104 unique_ptr_vmem ptr_64k_noalloc(
105 new (sandbox::NT_PAGE, base_address) char[KIB(64)]);
106 EXPECT_EQ(nullptr, ptr_64k_noalloc.get());
107 }
108
109 // Test the 512k block which exists at the end of the maximum allocation
110 // boundary.
111 void Test512kBlock(char* base_address) {
112 // This should fail as it'll just be out of range.
113 unique_ptr_vmem ptr_512k_noalloc(
114 new (sandbox::NT_PAGE, base_address) char[KIB(512)]);
115 EXPECT_EQ(nullptr, ptr_512k_noalloc.get());
116 // Check that moving base address we can allocate the 512k block.
117 unique_ptr_vmem ptr_512k(
118 new (sandbox::NT_PAGE, base_address + GIB(1)) char[KIB(512)]);
119 EXPECT_EQ(base_address + GIB(2), ptr_512k.get());
120 // Free pointer first.
121 ptr_512k.reset();
122 ptr_512k.reset(new (sandbox::NT_PAGE, base_address + GIB(2)) char[KIB(512)]);
123 EXPECT_EQ(base_address + GIB(2), ptr_512k.get());
124 }
125
126 // Test we can allocate appropriate blocks even when starting at an unaligned
127 // address.
128 void TestUnalignedRange(char* base_address) {
129 char* unaligned_base = base_address + 123456;
130 unique_ptr_vmem ptr_256k(
131 new (sandbox::NT_PAGE, unaligned_base) char[KIB(256)]);
132 EXPECT_EQ(base_address + GIB(1) + MIB(512) - KIB(256), ptr_256k.get());
133 unique_ptr_vmem ptr_64k(new (sandbox::NT_PAGE, unaligned_base) char[KIB(64)]);
134 EXPECT_EQ(base_address + MIB(512) - KIB(64), ptr_64k.get());
135 unique_ptr_vmem ptr_128k(
136 new (sandbox::NT_PAGE, unaligned_base) char[KIB(128)]);
137 EXPECT_EQ(base_address + GIB(1) - KIB(128), ptr_128k.get());
138 }
139
140 // Test maximum number of available allocations within the predefined pattern.
141 void TestMaxAllocations(char* base_address) {
142 // There's only 7 64k blocks in the first 2g which we can fill.
143 unique_ptr_vmem ptr_1(new (sandbox::NT_PAGE, base_address) char[1]);
144 EXPECT_NE(nullptr, ptr_1.get());
145 unique_ptr_vmem ptr_2(new (sandbox::NT_PAGE, base_address) char[1]);
146 EXPECT_NE(nullptr, ptr_2.get());
147 unique_ptr_vmem ptr_3(new (sandbox::NT_PAGE, base_address) char[1]);
148 EXPECT_NE(nullptr, ptr_3.get());
149 unique_ptr_vmem ptr_4(new (sandbox::NT_PAGE, base_address) char[1]);
150 EXPECT_NE(nullptr, ptr_4.get());
151 unique_ptr_vmem ptr_5(new (sandbox::NT_PAGE, base_address) char[1]);
152 EXPECT_NE(nullptr, ptr_5.get());
153 unique_ptr_vmem ptr_6(new (sandbox::NT_PAGE, base_address) char[1]);
154 EXPECT_NE(nullptr, ptr_6.get());
155 unique_ptr_vmem ptr_7(new (sandbox::NT_PAGE, base_address) char[1]);
156 EXPECT_NE(nullptr, ptr_7.get());
157 unique_ptr_vmem ptr_8(new (sandbox::NT_PAGE, base_address) char[1]);
158 EXPECT_EQ(nullptr, ptr_8.get());
159 }
160
161 // Test extreme allocations we know should fail.
162 void TestExtremes() {
163 unique_ptr_vmem ptr_null(new (sandbox::NT_PAGE, nullptr) char[1]);
164 EXPECT_EQ(nullptr, ptr_null.get());
165 unique_ptr_vmem ptr_too_large(
166 new (sandbox::NT_PAGE, reinterpret_cast<void*>(0x1000000)) char[GIB(4)]);
167 EXPECT_EQ(nullptr, ptr_too_large.get());
168 unique_ptr_vmem ptr_overflow(
169 new (sandbox::NT_PAGE, reinterpret_cast<void*>(SIZE_MAX)) char[1]);
170 EXPECT_EQ(nullptr, ptr_overflow.get());
171 unique_ptr_vmem ptr_invalid(new (
172 sandbox::NT_PAGE, reinterpret_cast<void*>(SIZE_MAX - 0x1000000)) char[1]);
173 EXPECT_EQ(nullptr, ptr_invalid.get());
174 }
175
176 // Test nearest allocator, only do this for 64 bit. We test through the exposed
177 // new operator as we can't call the AllocateNearTo function directly.
178 TEST(SandboxNtUtil, NearestAllocator) {
179 InitGlobalNt();
180 std::vector<unique_ptr_vmem> mem_range;
181 AllocateTestRange(&mem_range);
182 ASSERT_LT(0U, mem_range.size());
183 char* base_address = static_cast<char*>(mem_range[0].get());
184
185 TestAlignedRange(base_address);
186 Test512kBlock(base_address);
187 TestUnalignedRange(base_address);
188 TestMaxAllocations(base_address);
189 TestExtremes();
190 }
191
192 #endif // defined(_WIN64)
193
46 } // namespace 194 } // namespace
47 } // namespace sandbox 195 } // namespace sandbox
OLDNEW
« no previous file with comments | « 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