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

Side by Side Diff: sandbox/win/src/sandbox_nt_util.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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "sandbox/win/src/sandbox_nt_util.h" 5 #include "sandbox/win/src/sandbox_nt_util.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <string> 10 #include <string>
11 11
12 #include "base/win/pe_image.h" 12 #include "base/win/pe_image.h"
13 #include "sandbox/win/src/sandbox_factory.h" 13 #include "sandbox/win/src/sandbox_factory.h"
14 #include "sandbox/win/src/target_services.h" 14 #include "sandbox/win/src/target_services.h"
15 15
16 namespace sandbox { 16 namespace sandbox {
17 17
18 // This is the list of all imported symbols from ntdll.dll. 18 // This is the list of all imported symbols from ntdll.dll.
19 SANDBOX_INTERCEPT NtExports g_nt; 19 SANDBOX_INTERCEPT NtExports g_nt;
20 20
21 } // namespace sandbox 21 } // namespace sandbox
22 22
23 namespace { 23 namespace {
24 24
25 #if defined(_WIN64) 25 #if defined(_WIN64)
26 inline char* AlignToBoundary(void* ptr, size_t increment) {
Will Harris 2016/08/19 16:39:52 can you add some brief function comments on both o
27 const size_t kAllocationGranularity = (64 * 1024) - 1;
28 DWORD_PTR ptr_int = reinterpret_cast<DWORD_PTR>(ptr);
Will Harris 2016/08/19 16:39:52 can you use uintptr_t here unless you are directly
29 DWORD_PTR ret_ptr =
30 (ptr_int + increment + kAllocationGranularity) & ~kAllocationGranularity;
31 // Check for overflow.
32 if (ret_ptr < ptr_int)
33 return nullptr;
34 return reinterpret_cast<char*>(ret_ptr);
35 }
36
26 void* AllocateNearTo(void* source, size_t size) { 37 void* AllocateNearTo(void* source, size_t size) {
27 using sandbox::g_nt; 38 using sandbox::g_nt;
39 // 2GiB max size window.
40 const size_t kMaxSize = 0x80000000ULL;
41 // We don't support null as a base.
42 if (source == nullptr)
43 return nullptr;
44 if (size > kMaxSize)
45 return nullptr;
28 46
29 // Start with 1 GB above the source. 47 char* base = AlignToBoundary(source, 0);
30 const size_t kOneGB = 0x40000000; 48 if (base == nullptr)
31 void* base = reinterpret_cast<char*>(source) + kOneGB; 49 return nullptr;
32 SIZE_T actual_size = size; 50 // Set top address to be base + 2GiB. If we can't find in this range we're
33 ULONG_PTR zero_bits = 0; // Not the correct type if used. 51 // stuck.
34 ULONG type = MEM_RESERVE; 52 const char* top_address = base + kMaxSize;
35 53
36 NTSTATUS ret; 54 while (base < top_address) {
37 int attempts = 0; 55 MEMORY_BASIC_INFORMATION mem_info;
38 for (; attempts < 41; attempts++) { 56 NTSTATUS status =
39 ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, zero_bits, 57 g_nt.QueryVirtualMemory(NtCurrentProcess, base, MemoryBasicInformation,
40 &actual_size, type, PAGE_READWRITE); 58 &mem_info, sizeof(mem_info), nullptr);
41 if (NT_SUCCESS(ret)) { 59 if (!NT_SUCCESS(status))
42 if (base < source ||
43 base >= reinterpret_cast<char*>(source) + 4 * kOneGB) {
44 // We won't be able to patch this dll.
45 VERIFY_SUCCESS(g_nt.FreeVirtualMemory(NtCurrentProcess, &base, &size,
46 MEM_RELEASE));
47 return NULL;
48 }
49 break; 60 break;
61
62 if ((mem_info.State == MEM_FREE) && (mem_info.RegionSize >= size)) {
63 void* ret_base = mem_info.BaseAddress;
64 status =
65 g_nt.AllocateVirtualMemory(NtCurrentProcess, &ret_base, 0, &size,
66 MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
67 if (NT_SUCCESS(status))
68 return ret_base;
50 } 69 }
51 70
52 if (attempts == 30) { 71 base = AlignToBoundary(mem_info.BaseAddress, mem_info.RegionSize);
53 // Try the first GB. 72 if (base == nullptr)
54 base = reinterpret_cast<char*>(source); 73 break;
55 } else if (attempts == 40) {
56 // Try the highest available address.
57 base = NULL;
58 type |= MEM_TOP_DOWN;
59 }
60
61 // Try 100 MB higher.
62 base = reinterpret_cast<char*>(base) + 100 * 0x100000;
63 } 74 }
64 75 return nullptr;
65 if (attempts == 41)
66 return NULL;
67
68 ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, zero_bits,
69 &actual_size, MEM_COMMIT, PAGE_READWRITE);
70
71 if (!NT_SUCCESS(ret)) {
72 VERIFY_SUCCESS(g_nt.FreeVirtualMemory(NtCurrentProcess, &base, &size,
73 MEM_RELEASE));
74 base = NULL;
75 }
76
77 return base;
78 } 76 }
79 #else // defined(_WIN64). 77 #else // defined(_WIN64).
80 void* AllocateNearTo(void* source, size_t size) { 78 void* AllocateNearTo(void* source, size_t size) {
81 using sandbox::g_nt; 79 using sandbox::g_nt;
82 80
83 // In 32-bit processes allocations below 512k are predictable, so mark 81 // In 32-bit processes allocations below 512k are predictable, so mark
84 // anything in that range as reserved and retry until we get a good address. 82 // anything in that range as reserved and retry until we get a good address.
85 const void* const kMinAddress = reinterpret_cast<void*>(512 * 1024); 83 const void* const kMinAddress = reinterpret_cast<void*>(512 * 1024);
86 NTSTATUS ret; 84 NTSTATUS ret;
87 SIZE_T actual_size; 85 SIZE_T actual_size;
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 665
668 void* __cdecl operator new(size_t size, 666 void* __cdecl operator new(size_t size,
669 void* buffer, 667 void* buffer,
670 sandbox::AllocationType type) { 668 sandbox::AllocationType type) {
671 return buffer; 669 return buffer;
672 } 670 }
673 671
674 void __cdecl operator delete(void* memory, 672 void __cdecl operator delete(void* memory,
675 void* buffer, 673 void* buffer,
676 sandbox::AllocationType type) {} 674 sandbox::AllocationType type) {}
OLDNEW
« no previous file with comments | « no previous file | sandbox/win/src/sandbox_nt_util_unittest.cc » ('j') | sandbox/win/src/sandbox_nt_util_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698