OLD | NEW |
---|---|
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 Loading... | |
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 void AllocateTestRange(std::vector<unique_ptr_vmem>* mem_range) { | |
73 // Ensure we preallocate enough space in the vector to prevent unexpected | |
74 // allocations. | |
75 mem_range->reserve(5); | |
76 SIZE_T total_size = | |
77 MIB(512) + MIB(512) + MIB(512) + MIB(512) + KIB(512) + KIB(64); | |
78 unique_ptr_vmem ptr(static_cast<char*>( | |
79 ::VirtualAlloc(nullptr, total_size, MEM_RESERVE, PAGE_READWRITE))); | |
80 ASSERT_NE(nullptr, ptr.get()); | |
81 char* base_address = ptr.get(); | |
82 char* orig_base = base_address; | |
83 ptr.reset(); | |
84 AllocateBlock(MIB(512), KIB(64), &base_address, mem_range); | |
85 AllocateBlock(MIB(512), KIB(128), &base_address, mem_range); | |
86 AllocateBlock(MIB(512), KIB(256), &base_address, mem_range); | |
87 AllocateBlock(MIB(512) + KIB(512), KIB(512), &base_address, mem_range); | |
88 // Allocate a memory block at end to act as an upper bound. | |
89 AllocateBlock(KIB(64), 0, &base_address, mem_range); | |
90 ASSERT_EQ(total_size, static_cast<SIZE_T>(base_address - orig_base)); | |
91 } | |
92 | |
93 void TestAlignedRange(char* base_address) { | |
94 unique_ptr_vmem ptr_256k(new (sandbox::NT_PAGE, base_address) char[KIB(256)]); | |
95 EXPECT_EQ(base_address + GIB(1) + MIB(512) - KIB(256), ptr_256k.get()); | |
96 unique_ptr_vmem ptr_64k(new (sandbox::NT_PAGE, base_address) char[KIB(64)]); | |
97 EXPECT_EQ(base_address + MIB(512) - KIB(64), ptr_64k.get()); | |
98 unique_ptr_vmem ptr_128k(new (sandbox::NT_PAGE, base_address) char[KIB(128)]); | |
99 EXPECT_EQ(base_address + GIB(1) - KIB(128), ptr_128k.get()); | |
100 // We will have run out of space here so should also fail. | |
101 unique_ptr_vmem ptr_64k_noalloc( | |
102 new (sandbox::NT_PAGE, base_address) char[KIB(64)]); | |
103 EXPECT_EQ(nullptr, ptr_64k_noalloc.get()); | |
104 } | |
105 | |
106 void Test512kBlock(char* base_address) { | |
107 // This should fail as it'll just be out of range. | |
108 unique_ptr_vmem ptr_512k_noalloc( | |
109 new (sandbox::NT_PAGE, base_address) char[KIB(512)]); | |
110 EXPECT_EQ(nullptr, ptr_512k_noalloc.get()); | |
111 // Check that moving base address we can allocate the 512k block. | |
112 unique_ptr_vmem ptr_512k( | |
113 new (sandbox::NT_PAGE, base_address + GIB(1)) char[KIB(512)]); | |
114 EXPECT_EQ(base_address + GIB(2), ptr_512k.get()); | |
115 // Free pointer first. | |
116 ptr_512k.reset(); | |
117 ptr_512k.reset(new (sandbox::NT_PAGE, base_address + GIB(2)) char[KIB(512)]); | |
118 EXPECT_EQ(base_address + GIB(2), ptr_512k.get()); | |
119 } | |
120 | |
121 void TestUnalignedRange(char* base_address) { | |
122 char* unaligned_base = base_address + 123456; | |
123 unique_ptr_vmem ptr_256k( | |
124 new (sandbox::NT_PAGE, unaligned_base) char[KIB(256)]); | |
125 EXPECT_EQ(base_address + GIB(1) + MIB(512) - KIB(256), ptr_256k.get()); | |
126 unique_ptr_vmem ptr_64k(new (sandbox::NT_PAGE, unaligned_base) char[KIB(64)]); | |
127 EXPECT_EQ(base_address + MIB(512) - KIB(64), ptr_64k.get()); | |
128 unique_ptr_vmem ptr_128k( | |
129 new (sandbox::NT_PAGE, unaligned_base) char[KIB(128)]); | |
130 EXPECT_EQ(base_address + GIB(1) - KIB(128), ptr_128k.get()); | |
131 } | |
132 | |
133 void TestMaxAllocations(char* base_address) { | |
134 // There's only 7 64k blocks in the first 2g which we can fill. | |
135 unique_ptr_vmem ptr_1(new (sandbox::NT_PAGE, base_address) char[1]); | |
136 EXPECT_NE(nullptr, ptr_1.get()); | |
137 unique_ptr_vmem ptr_2(new (sandbox::NT_PAGE, base_address) char[1]); | |
138 EXPECT_NE(nullptr, ptr_2.get()); | |
139 unique_ptr_vmem ptr_3(new (sandbox::NT_PAGE, base_address) char[1]); | |
140 EXPECT_NE(nullptr, ptr_3.get()); | |
141 unique_ptr_vmem ptr_4(new (sandbox::NT_PAGE, base_address) char[1]); | |
142 EXPECT_NE(nullptr, ptr_4.get()); | |
143 unique_ptr_vmem ptr_5(new (sandbox::NT_PAGE, base_address) char[1]); | |
144 EXPECT_NE(nullptr, ptr_5.get()); | |
145 unique_ptr_vmem ptr_6(new (sandbox::NT_PAGE, base_address) char[1]); | |
146 EXPECT_NE(nullptr, ptr_6.get()); | |
147 unique_ptr_vmem ptr_7(new (sandbox::NT_PAGE, base_address) char[1]); | |
148 EXPECT_NE(nullptr, ptr_7.get()); | |
149 unique_ptr_vmem ptr_8(new (sandbox::NT_PAGE, base_address) char[1]); | |
150 EXPECT_EQ(nullptr, ptr_8.get()); | |
151 } | |
152 | |
153 void TestExtremes() { | |
154 unique_ptr_vmem ptr_null(new (sandbox::NT_PAGE, nullptr) char[1]); | |
155 EXPECT_EQ(nullptr, ptr_null.get()); | |
156 unique_ptr_vmem ptr_too_large( | |
157 new (sandbox::NT_PAGE, reinterpret_cast<void*>(0x1000000)) char[GIB(4)]); | |
158 EXPECT_EQ(nullptr, ptr_too_large.get()); | |
159 unique_ptr_vmem ptr_overflow( | |
160 new (sandbox::NT_PAGE, reinterpret_cast<void*>(SIZE_MAX)) char[1]); | |
161 EXPECT_EQ(nullptr, ptr_overflow.get()); | |
162 unique_ptr_vmem ptr_invalid(new ( | |
163 sandbox::NT_PAGE, reinterpret_cast<void*>(SIZE_MAX - 0x1000000)) char[1]); | |
164 EXPECT_EQ(nullptr, ptr_invalid.get()); | |
165 } | |
166 | |
167 // 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
| |
168 TEST(SandboxNtUtil, NearestAllocator) { | |
169 InitGlobalNt(); | |
170 std::vector<unique_ptr_vmem> mem_range; | |
171 AllocateTestRange(&mem_range); | |
172 ASSERT_LT(0U, mem_range.size()); | |
173 char* base_address = static_cast<char*>(mem_range[0].get()); | |
174 | |
175 TestAlignedRange(base_address); | |
176 Test512kBlock(base_address); | |
177 TestUnalignedRange(base_address); | |
178 TestMaxAllocations(base_address); | |
179 TestExtremes(); | |
180 } | |
181 | |
182 #endif // defined(_WIN64) | |
183 | |
46 } // namespace | 184 } // namespace |
47 } // namespace sandbox | 185 } // namespace sandbox |
OLD | NEW |