OLD | NEW |
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/process_mitigations.h" | 5 #include "sandbox/win/src/process_mitigations.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 namespace sandbox { | 32 namespace sandbox { |
33 | 33 |
34 bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags flags) { | 34 bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags flags) { |
35 if (!CanSetProcessMitigationsPostStartup(flags)) | 35 if (!CanSetProcessMitigationsPostStartup(flags)) |
36 return false; | 36 return false; |
37 | 37 |
38 base::win::Version version = base::win::GetVersion(); | 38 base::win::Version version = base::win::GetVersion(); |
39 HMODULE module = ::GetModuleHandleA("kernel32.dll"); | 39 HMODULE module = ::GetModuleHandleA("kernel32.dll"); |
40 | 40 |
41 if (version >= base::win::VERSION_VISTA && | 41 if (flags & MITIGATION_DLL_SEARCH_ORDER) { |
42 (flags & MITIGATION_DLL_SEARCH_ORDER)) { | |
43 SetDefaultDllDirectoriesFunction set_default_dll_directories = | 42 SetDefaultDllDirectoriesFunction set_default_dll_directories = |
44 reinterpret_cast<SetDefaultDllDirectoriesFunction>( | 43 reinterpret_cast<SetDefaultDllDirectoriesFunction>( |
45 ::GetProcAddress(module, "SetDefaultDllDirectories")); | 44 ::GetProcAddress(module, "SetDefaultDllDirectories")); |
46 | 45 |
47 // Check for SetDefaultDllDirectories since it requires KB2533623. | 46 // Check for SetDefaultDllDirectories since it requires KB2533623. |
48 if (set_default_dll_directories) { | 47 if (set_default_dll_directories) { |
49 if (!set_default_dll_directories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) && | 48 if (!set_default_dll_directories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) && |
50 ERROR_ACCESS_DENIED != ::GetLastError()) { | 49 ERROR_ACCESS_DENIED != ::GetLastError()) { |
51 return false; | 50 return false; |
52 } | 51 } |
53 } | 52 } |
54 } | 53 } |
55 | 54 |
56 // Set the heap to terminate on corruption | 55 // Set the heap to terminate on corruption |
57 if (version >= base::win::VERSION_VISTA && | 56 if (flags & MITIGATION_HEAP_TERMINATE) { |
58 (flags & MITIGATION_HEAP_TERMINATE)) { | |
59 if (!::HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, | 57 if (!::HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, |
60 NULL, 0) && | 58 NULL, 0) && |
61 ERROR_ACCESS_DENIED != ::GetLastError()) { | 59 ERROR_ACCESS_DENIED != ::GetLastError()) { |
62 return false; | 60 return false; |
63 } | 61 } |
64 } | 62 } |
65 | 63 |
66 if (version >= base::win::VERSION_WIN7 && | 64 if (flags & MITIGATION_HARDEN_TOKEN_IL_POLICY) { |
67 (flags & MITIGATION_HARDEN_TOKEN_IL_POLICY)) { | |
68 DWORD error = HardenProcessIntegrityLevelPolicy(); | 65 DWORD error = HardenProcessIntegrityLevelPolicy(); |
69 if ((error != ERROR_SUCCESS) && (error != ERROR_ACCESS_DENIED)) | 66 if ((error != ERROR_SUCCESS) && (error != ERROR_ACCESS_DENIED)) |
70 return false; | 67 return false; |
71 } | 68 } |
72 | 69 |
73 #if !defined(_WIN64) // DEP is always enabled on 64-bit. | 70 #if !defined(_WIN64) // DEP is always enabled on 64-bit. |
74 if (flags & MITIGATION_DEP) { | 71 if (flags & MITIGATION_DEP) { |
75 DWORD dep_flags = PROCESS_DEP_ENABLE; | 72 DWORD dep_flags = PROCESS_DEP_ENABLE; |
76 // DEP support is quirky on XP, so don't force a failure in that case. | |
77 const bool return_on_fail = version >= base::win::VERSION_VISTA; | |
78 | 73 |
79 if (flags & MITIGATION_DEP_NO_ATL_THUNK) | 74 if (flags & MITIGATION_DEP_NO_ATL_THUNK) |
80 dep_flags |= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION; | 75 dep_flags |= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION; |
81 | 76 |
82 SetProcessDEPPolicyFunction set_process_dep_policy = | 77 SetProcessDEPPolicyFunction set_process_dep_policy = |
83 reinterpret_cast<SetProcessDEPPolicyFunction>( | 78 reinterpret_cast<SetProcessDEPPolicyFunction>( |
84 ::GetProcAddress(module, "SetProcessDEPPolicy")); | 79 ::GetProcAddress(module, "SetProcessDEPPolicy")); |
85 if (set_process_dep_policy) { | 80 if (set_process_dep_policy) { |
86 if (!set_process_dep_policy(dep_flags) && | 81 if (!set_process_dep_policy(dep_flags) && |
87 ERROR_ACCESS_DENIED != ::GetLastError() && return_on_fail) { | 82 ERROR_ACCESS_DENIED != ::GetLastError()) { |
88 return false; | 83 return false; |
89 } | 84 } |
90 } else { | 85 } else |
91 // We're on XP sp2, so use the less standard approach. | 86 return false; |
92 // For reference: http://www.uninformed.org/?v=2&a=4 | |
93 static const int MEM_EXECUTE_OPTION_DISABLE = 2; | |
94 static const int MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4; | |
95 static const int MEM_EXECUTE_OPTION_PERMANENT = 8; | |
96 | |
97 NtSetInformationProcessFunction set_information_process = NULL; | |
98 ResolveNTFunctionPtr("NtSetInformationProcess", | |
99 &set_information_process); | |
100 if (!set_information_process) | |
101 return false; | |
102 ULONG dep = MEM_EXECUTE_OPTION_DISABLE | MEM_EXECUTE_OPTION_PERMANENT; | |
103 if (!(dep_flags & PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION)) | |
104 dep |= MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION; | |
105 if (!SUCCEEDED(set_information_process(GetCurrentProcess(), | |
106 ProcessExecuteFlags, | |
107 &dep, sizeof(dep))) && | |
108 ERROR_ACCESS_DENIED != ::GetLastError() && return_on_fail) { | |
109 return false; | |
110 } | |
111 } | |
112 } | 87 } |
113 #endif | 88 #endif |
114 | 89 |
115 // This is all we can do in Win7 and below. | 90 // This is all we can do in Win7 and below. |
116 if (version < base::win::VERSION_WIN8) | 91 if (version < base::win::VERSION_WIN8) |
117 return true; | 92 return true; |
118 | 93 |
119 SetProcessMitigationPolicyFunction set_process_mitigation_policy = | 94 SetProcessMitigationPolicyFunction set_process_mitigation_policy = |
120 reinterpret_cast<SetProcessMitigationPolicyFunction>( | 95 reinterpret_cast<SetProcessMitigationPolicyFunction>( |
121 ::GetProcAddress(module, "SetProcessMitigationPolicy")); | 96 ::GetProcAddress(module, "SetProcessMitigationPolicy")); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 #elif defined(_M_IX86) | 197 #elif defined(_M_IX86) |
223 // A 64-bit flags attribute is illegal on 32-bit Win 7 and below. | 198 // A 64-bit flags attribute is illegal on 32-bit Win 7 and below. |
224 if (version < base::win::VERSION_WIN8) | 199 if (version < base::win::VERSION_WIN8) |
225 *size = sizeof(DWORD); | 200 *size = sizeof(DWORD); |
226 else | 201 else |
227 *size = sizeof(*policy_flags); | 202 *size = sizeof(*policy_flags); |
228 #else | 203 #else |
229 #error This platform is not supported. | 204 #error This platform is not supported. |
230 #endif | 205 #endif |
231 | 206 |
232 // Nothing for Win XP or Vista. | |
233 if (version <= base::win::VERSION_VISTA) | |
234 return; | |
235 | |
236 // DEP and SEHOP are not valid for 64-bit Windows | 207 // DEP and SEHOP are not valid for 64-bit Windows |
237 #if !defined(_WIN64) | 208 #if !defined(_WIN64) |
238 if (flags & MITIGATION_DEP) { | 209 if (flags & MITIGATION_DEP) { |
239 *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE; | 210 *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE; |
240 if (!(flags & MITIGATION_DEP_NO_ATL_THUNK)) | 211 if (!(flags & MITIGATION_DEP_NO_ATL_THUNK)) |
241 *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE; | 212 *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE; |
242 } | 213 } |
243 | 214 |
244 if (flags & MITIGATION_SEHOP) | 215 if (flags & MITIGATION_SEHOP) |
245 *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE; | 216 *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 | 276 |
306 if (flags & MITIGATION_IMAGE_LOAD_NO_LOW_LABEL) { | 277 if (flags & MITIGATION_IMAGE_LOAD_NO_LOW_LABEL) { |
307 *policy_flags |= | 278 *policy_flags |= |
308 PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_LOW_LABEL_ALWAYS_ON; | 279 PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_LOW_LABEL_ALWAYS_ON; |
309 } | 280 } |
310 } | 281 } |
311 | 282 |
312 MitigationFlags FilterPostStartupProcessMitigations(MitigationFlags flags) { | 283 MitigationFlags FilterPostStartupProcessMitigations(MitigationFlags flags) { |
313 base::win::Version version = base::win::GetVersion(); | 284 base::win::Version version = base::win::GetVersion(); |
314 | 285 |
315 // Windows XP SP2+. | |
316 if (version < base::win::VERSION_VISTA) { | |
317 return flags & (MITIGATION_DEP | | |
318 MITIGATION_DEP_NO_ATL_THUNK); | |
319 } | |
320 | |
321 // Windows Vista | |
322 if (version < base::win::VERSION_WIN7) { | |
323 return flags & (MITIGATION_BOTTOM_UP_ASLR | | |
324 MITIGATION_DLL_SEARCH_ORDER | | |
325 MITIGATION_HEAP_TERMINATE); | |
326 } | |
327 | |
328 // Windows 7. | 286 // Windows 7. |
329 if (version < base::win::VERSION_WIN8) { | 287 if (version < base::win::VERSION_WIN8) { |
330 return flags & (MITIGATION_BOTTOM_UP_ASLR | | 288 return flags & (MITIGATION_BOTTOM_UP_ASLR | |
331 MITIGATION_DLL_SEARCH_ORDER | | 289 MITIGATION_DLL_SEARCH_ORDER | |
332 MITIGATION_HEAP_TERMINATE); | 290 MITIGATION_HEAP_TERMINATE); |
333 } | 291 } |
334 | 292 |
335 // Windows 8 and above. | 293 // Windows 8 and above. |
336 return flags & (MITIGATION_BOTTOM_UP_ASLR | | 294 return flags & (MITIGATION_BOTTOM_UP_ASLR | |
337 MITIGATION_DLL_SEARCH_ORDER); | 295 MITIGATION_DLL_SEARCH_ORDER); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 } | 343 } |
386 | 344 |
387 bool CanSetProcessMitigationsPreStartup(MitigationFlags flags) { | 345 bool CanSetProcessMitigationsPreStartup(MitigationFlags flags) { |
388 // These mitigations cannot be enabled prior to startup. | 346 // These mitigations cannot be enabled prior to startup. |
389 return !(flags & (MITIGATION_STRICT_HANDLE_CHECKS | | 347 return !(flags & (MITIGATION_STRICT_HANDLE_CHECKS | |
390 MITIGATION_DLL_SEARCH_ORDER)); | 348 MITIGATION_DLL_SEARCH_ORDER)); |
391 } | 349 } |
392 | 350 |
393 } // namespace sandbox | 351 } // namespace sandbox |
394 | 352 |
OLD | NEW |