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

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

Powered by Google App Engine
This is Rietveld 408576698