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

Side by Side Diff: sandbox/win/src/process_mitigations.cc

Issue 10690058: Add sandbox support for Windows process mitigations (Closed) Base URL: https://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 3 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "sandbox/win/src/process_mitigations.h"
6
7 #include "base/win/windows_version.h"
8 #include "sandbox/win/src/nt_internals.h"
9 #include "sandbox/win/src/sandbox_utils.h"
10 #include "sandbox/win/src/win_utils.h"
11
12 namespace {
13
14 // Functions for enabling policies.
15 typedef BOOL (WINAPI *SetProcessDEPPolicyFunction)(DWORD dwFlags);
16
17 typedef BOOL (WINAPI *SetProcessMitigationPolicyFunction)(
18 PROCESS_MITIGATION_POLICY mitigation_policy,
19 PVOID buffer,
20 SIZE_T length);
21
22 typedef BOOL (WINAPI *SetDefaultDllDirectoriesFunction)(
23 DWORD DirectoryFlags);
24
25 } // namespace
26
27 namespace sandbox {
28
29 bool SetProcessMitigationsForCurrentProcess(uint64 flags) {
30 if (!CanSetProcessMitigationsPostStartup(flags))
31 return false;
32
33 HMODULE module = ::GetModuleHandleW(L"kernel32.dll");
34
35 // We can't apply anything before Win XP, so just return cleanly.
36 if (!IsXPSP2OrLater())
37 return true;
38
39 if (flags & MITIGATION_DLL_SEARCH) {
40 SetDefaultDllDirectoriesFunction set_default_dll_directories =
41 reinterpret_cast<SetDefaultDllDirectoriesFunction>(
42 ::GetProcAddress(module, "SetDefaultDllDirectories"));
43
44 // Check for SetDefaultDllDirectories since it requires KB2533623.
45 if (set_default_dll_directories) {
46 if (!set_default_dll_directories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS))
47 return false;
48 }
49 }
50
51 base::win::Version version = base::win::GetVersion();
52
53 // Set the heap to terminate on corruption
54 if (flags & MITIGATION_HEAP_TERMINATE) {
55 if (!::HeapSetInformation(NULL, HeapEnableTerminationOnCorruption,
56 NULL, 0))
57 return false;
58 }
59
60 #ifndef _WIN64 // DEP is always enabled on 64-bit.
61 if (flags & MITIGATION_DEP) {
62 DWORD dep_flags = PROCESS_DEP_ENABLE;
63
64 if (flags & MITIGATION_DEP_NO_ATL_THUNK)
65 dep_flags |= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION;
66
67 SetProcessDEPPolicyFunction set_process_dep_policy =
68 reinterpret_cast<SetProcessDEPPolicyFunction>(
69 ::GetProcAddress(module, "SetProcessDEPPolicy"));
70 if (set_process_dep_policy) {
71 if (!set_process_dep_policy(dep_flags) &&
72 ERROR_ACCESS_DENIED != ::GetLastError()) {
73 return false;
74 }
75 } else {
76 // We're on XP sp2, so use the less standard approach.
77 // For reference: http://www.uninformed.org/?v=2&a=4
78 const int MEM_EXECUTE_OPTION_ENABLE = 1;
79 const int MEM_EXECUTE_OPTION_DISABLE = 2;
80 const int MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4;
81 const int MEM_EXECUTE_OPTION_PERMANENT = 8;
82
83 NtSetInformationProcessFunction set_information_process = NULL;
84 ResolveNTFunctionPtr("NtSetInformationProcess",
85 &set_information_process);
86 if (!set_information_process)
87 return false;
88 ULONG dep = MEM_EXECUTE_OPTION_DISABLE | MEM_EXECUTE_OPTION_PERMANENT;
89 if (!(dep_flags & PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION))
90 dep |= MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION;
91 if (!SUCCEEDED(set_information_process(GetCurrentProcess(),
92 ProcessExecuteFlags,
93 &dep, sizeof(dep))) &&
94 ERROR_ACCESS_DENIED != ::GetLastError()) {
95 return false;
96 }
97 }
98 }
99 #endif
100
101 // This is all we can do in Win7 and below
102 if (version < base::win::VERSION_WIN8)
103 return true;
104
105 // Load the Win8 API on demand.
106 SetProcessMitigationPolicyFunction set_process_mitigation_policy =
107 reinterpret_cast<SetProcessMitigationPolicyFunction>(
108 ::GetProcAddress(module, "SetProcessMitigationPolicy"));
109 if (!set_process_mitigation_policy)
110 return false;
111
112 // Enable ASLR policies.
113 if (flags & MITIGATION_RELOCATE_IMAGE) {
114 PROCESS_MITIGATION_ASLR_POLICY policy = { 0 };
115 policy.EnableForceRelocateImages = true;
116 policy.DisallowStrippedImages = (flags &
117 MITIGATION_RELOCATE_IMAGE_REQUIRED) ==
118 MITIGATION_RELOCATE_IMAGE_REQUIRED;
119
120 if (!set_process_mitigation_policy(ProcessASLRPolicy, &policy,
121 sizeof(policy)) &&
122 ERROR_ACCESS_DENIED != ::GetLastError()) {
123 return false;
124 }
125 }
126
127 // Enable strict handle policies.
128 if (flags & MITIGATION_STRICT_HANDLE_CHECKS) {
129 PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy = { 0 };
130 policy.HandleExceptionsPermanentlyEnabled =
131 policy.RaiseExceptionOnInvalidHandleReference = true;
132
133 if (!set_process_mitigation_policy(ProcessStrictHandleCheckPolicy, &policy,
134 sizeof(policy)) &&
135 ERROR_ACCESS_DENIED != ::GetLastError()) {
136 return false;
137 }
138 }
139
140 // Enable system call policies.
141 if (flags & MITIGATION_WIN32K_DISABLE) {
142 PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = { 0 };
143 policy.DisallowWin32kSystemCalls = true;
144
145 if (!set_process_mitigation_policy(ProcessSystemCallDisablePolicy, &policy,
146 sizeof(policy)) &&
147 ERROR_ACCESS_DENIED != ::GetLastError()) {
148 return false;
149 }
150 }
151
152 // Enable system call policies.
153 if (flags & MITIGATION_EXTENSION_DLL_DISABLE) {
154 PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy = { 0 };
155 policy.DisableExtensionPoints = true;
156
157 if (!set_process_mitigation_policy(ProcessExtensionPointDisablePolicy,
158 &policy, sizeof(policy)) &&
159 ERROR_ACCESS_DENIED != ::GetLastError()) {
160 return false;
161 }
162 }
163
164 return true;
165 }
166
167 DWORD64 GetProcessMitigationPolicyFlags(uint64 flags) {
168 base::win::Version version = base::win::GetVersion();
169
170 // Nothing for Win XP
171 if (version < base::win::VERSION_VISTA)
172 return 0;
173
174 DWORD64 real_flags = 0;
175 if (flags & MITIGATION_DEP) {
176 real_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE;
177 if (!(flags & MITIGATION_DEP_NO_ATL_THUNK))
178 real_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE;
179 }
180
181 if (flags & MITIGATION_SEHOP)
182 real_flags |= PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE;
183
184 // Win 7 and Vista
185 if (version < base::win::VERSION_WIN8)
186 return real_flags;
187
188 if (flags & MITIGATION_RELOCATE_IMAGE) {
189 real_flags |=
190 PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON;
191 if (flags & MITIGATION_RELOCATE_IMAGE_REQUIRED) {
192 real_flags |=
193 PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON_REQ _RELOCS;
194 }
195 }
196
197 if (flags & MITIGATION_HEAP_TERMINATE)
198 real_flags |= PROCESS_CREATION_MITIGATION_POLICY_HEAP_TERMINATE_ALWAYS_ON;
199
200 if (flags & MITIGATION_BOTTOM_UP_ASLR)
201 real_flags |= PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_ON;
202
203 if (flags & MITIGATION_HIGH_ENTROPY_ASLR) {
204 real_flags |=
205 PROCESS_CREATION_MITIGATION_POLICY_HIGH_ENTROPY_ASLR_ALWAYS_ON;
206 }
207
208 if (flags & MITIGATION_STRICT_HANDLE_CHECKS) {
209 real_flags |=
210 PROCESS_CREATION_MITIGATION_POLICY_STRICT_HANDLE_CHECKS_ALWAYS_ON;
211 }
212
213 if (flags & MITIGATION_WIN32K_DISABLE) {
214 real_flags |=
215 PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON;
216 }
217
218 if (flags & MITIGATION_EXTENSION_DLL_DISABLE) {
219 real_flags |=
220 PROCESS_CREATION_MITIGATION_POLICY_EXTENSION_POINT_DISABLE_ALWAYS_ON;
221 }
222
223 // Windows 8
224 return real_flags;
225 }
226
227 uint64 GetPostStartupProcessMitigations(uint64 flags) {
228 base::win::Version version = base::win::GetVersion();
229
230 // Windows XP SP2
231 if (version < base::win::VERSION_VISTA) {
232 return flags & (MITIGATION_DEP |
233 MITIGATION_DEP_NO_ATL_THUNK);
234
235 // Windows 7 and Vista
236 } else if (version < base::win::VERSION_WIN8) {
237 return flags & (MITIGATION_BOTTOM_UP_ASLR |
238 MITIGATION_DLL_SEARCH |
239 MITIGATION_HEAP_TERMINATE);
240 }
241
242 // Windows 8 and above.
243 return flags & (MITIGATION_BOTTOM_UP_ASLR |
244 MITIGATION_DLL_SEARCH);
245 }
246
247 bool SetProcessMitigationsForSuspendedProcess(HANDLE process, uint64 flags) {
248 if (flags & MITIGATION_BOTTOM_UP_ASLR) {
249 unsigned int limit;
250 rand_s(&limit);
251 char* ptr = 0;
252 const size_t kMask64k = 0xFFFF;
253 // Random range (512k-16.5mb) in 64k steps.
254 const char* end = ptr + ((((limit % 16384) + 512) * 1024) & ~kMask64k);
255 while (ptr < end) {
256 MEMORY_BASIC_INFORMATION memory_info;
257 if (!::VirtualQueryEx(process, ptr, &memory_info, sizeof(memory_info)))
258 break;
259 size_t size = std::min((memory_info.RegionSize + kMask64k) & ~kMask64k,
260 static_cast<SIZE_T>(end - ptr));
261 if (ptr && memory_info.State == MEM_FREE)
262 ::VirtualAllocEx(process, ptr, size, MEM_RESERVE, PAGE_NOACCESS);
263 ptr += size;
264 }
265 }
266
267 return true;
268 }
269
270 bool CanSetProcessMitigationsPostStartup(uint64 flags) {
271 // All of these can be set after startup.
272 return !(flags & ~(MITIGATION_HEAP_TERMINATE |
273 MITIGATION_DEP |
274 MITIGATION_DEP_NO_ATL_THUNK |
275 MITIGATION_RELOCATE_IMAGE |
276 MITIGATION_RELOCATE_IMAGE_REQUIRED |
277 MITIGATION_BOTTOM_UP_ASLR |
278 MITIGATION_STRICT_HANDLE_CHECKS |
279 MITIGATION_WIN32K_DISABLE |
280 MITIGATION_EXTENSION_DLL_DISABLE |
281 MITIGATION_DLL_SEARCH));
282 }
283
284 bool CanSetProcessMitigationsPreStartup(uint64 flags) {
285 // These flags must be set after startup.
286 return !(flags & (MITIGATION_STRICT_HANDLE_CHECKS |
287 MITIGATION_WIN32K_DISABLE));
288 }
289
290 } // namespace sandbox
291
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698