Index: sandbox/src/target_process.cc |
=================================================================== |
--- sandbox/src/target_process.cc (revision 145076) |
+++ sandbox/src/target_process.cc (working copy) |
@@ -10,6 +10,7 @@ |
#include "base/win/windows_version.h" |
#include "sandbox/src/crosscall_server.h" |
#include "sandbox/src/crosscall_client.h" |
+#include "sandbox/src/internal_types.h" |
#include "sandbox/src/policy_low_level.h" |
#include "sandbox/src/sandbox_types.h" |
#include "sandbox/src/sharedmem_ipc_server.h" |
@@ -55,8 +56,113 @@ |
} |
} |
-} |
+// This helper class wraps the STARTUPINFO structure and handles the |
+// additional attributes in STARTUPINFOEX. |
+class ScopedStartupInfo { |
+ public: |
+ ScopedStartupInfo() { |
+ memset(&startup_info_, 0, sizeof(startup_info_)); |
+ // Pre Windows Vista doesn't support STARTUPINFOEX. |
+ if (base::win::GetVersion() < base::win::VERSION_VISTA) { |
+ startup_info_.StartupInfo.cb = sizeof(STARTUPINFO); |
+ return; |
+ } |
+ |
+ startup_info_.StartupInfo.cb = sizeof(STARTUPINFOEX); |
cpu_(ooo_6.6-7.5)
2012/07/02 21:42:32
sizeof(startup_info_)
|
+ |
+ // Load the attribute API functions. |
+ if (!s_InitializeProcThreadAttributeList) { |
+ HMODULE module = ::GetModuleHandleW(sandbox::kKerneldllName); |
+ s_InitializeProcThreadAttributeList = |
+ reinterpret_cast<InitializeProcThreadAttributeListFunction>( |
+ ::GetProcAddress(module, "InitializeProcThreadAttributeList")); |
+ s_UpdateProcThreadAttribute = |
+ reinterpret_cast<UpdateProcThreadAttributeFunction>( |
+ ::GetProcAddress(module, "UpdateProcThreadAttribute")); |
+ s_DeleteProcThreadAttributeList = |
+ reinterpret_cast<DeleteProcThreadAttributeListFunction>( |
+ ::GetProcAddress(module, "DeleteProcThreadAttributeList")); |
+ } |
+ } |
+ |
+ ~ScopedStartupInfo() { |
+ if (startup_info_.lpAttributeList) { |
+ s_DeleteProcThreadAttributeList(startup_info_.lpAttributeList); |
+ delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList); |
+ } |
+ } |
+ |
+ // Initialize the attribute list to the specified number of entries. |
+ bool InitializeProcThreadAttributeList(DWORD attribute_count) { |
+ if (startup_info_.lpAttributeList) |
+ return false; |
+ |
+ SIZE_T size = 0; |
+ s_InitializeProcThreadAttributeList(NULL, attribute_count, 0, &size); |
+ if (size == 0) |
+ return false; |
+ |
+ startup_info_.lpAttributeList = |
+ reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(new BYTE[size]); |
+ if (!s_InitializeProcThreadAttributeList(startup_info_.lpAttributeList, |
+ attribute_count, 0, &size)) { |
+ delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList); |
+ return false; |
+ } |
+ |
+ return true; |
+ } |
+ |
+ // Sets one entry in the initialized attribute list. |
+ bool UpdateProcThreadAttribute(DWORD_PTR attribute, |
+ PVOID value, |
cpu_(ooo_6.6-7.5)
2012/07/02 21:42:32
PVOID --> void*
Interestingly we also mix SIZE_T
|
+ SIZE_T size) { |
+ if (!startup_info_.lpAttributeList) |
+ return false; |
+ return s_UpdateProcThreadAttribute(startup_info_.lpAttributeList, 0, |
+ attribute, value, size, NULL, NULL); |
+ } |
+ |
+ STARTUPINFO* data() { return &startup_info_.StartupInfo; } |
+ |
+ private: |
+ STARTUPINFOEX startup_info_; |
+ |
+ typedef BOOL (WINAPI *InitializeProcThreadAttributeListFunction)( |
+ LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, |
+ DWORD attribute_count, |
+ DWORD flags, |
+ PSIZE_T size); |
+ static InitializeProcThreadAttributeListFunction |
+ s_InitializeProcThreadAttributeList; |
+ |
+ typedef BOOL (WINAPI *UpdateProcThreadAttributeFunction)( |
+ LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, |
+ DWORD flags, |
+ DWORD_PTR attribute, |
+ PVOID value, |
+ SIZE_T size, |
+ PVOID previous_value, |
+ PSIZE_T return_size); |
+ static UpdateProcThreadAttributeFunction s_UpdateProcThreadAttribute; |
+ |
+ typedef VOID (WINAPI *DeleteProcThreadAttributeListFunction)( |
+ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList); |
+ static DeleteProcThreadAttributeListFunction s_DeleteProcThreadAttributeList; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ScopedStartupInfo); |
+}; |
+ |
+ScopedStartupInfo::InitializeProcThreadAttributeListFunction |
+ ScopedStartupInfo::s_InitializeProcThreadAttributeList; |
+ScopedStartupInfo::UpdateProcThreadAttributeFunction |
+ ScopedStartupInfo::s_UpdateProcThreadAttribute; |
+ScopedStartupInfo::DeleteProcThreadAttributeListFunction |
+ ScopedStartupInfo::s_DeleteProcThreadAttributeList; |
+ |
+} // namespace |
+ |
namespace sandbox { |
SANDBOX_INTERCEPT HANDLE g_shared_section; |
@@ -145,9 +251,32 @@ |
flags |= CREATE_BREAKAWAY_FROM_JOB; |
} |
- STARTUPINFO startup_info = {sizeof(STARTUPINFO)}; |
- if (desktop) { |
- startup_info.lpDesktop = desktop_name.get(); |
+ ScopedStartupInfo startup_info; |
+ if (desktop) |
+ startup_info.data()->lpDesktop = desktop_name.get(); |
+ if (base::win::GetVersion() >= base::win::VERSION_WIN7) { |
cpu_(ooo_6.6-7.5)
2012/07/02 21:42:32
space after line 256
|
+ flags |= EXTENDED_STARTUPINFO_PRESENT; |
+ DWORD_PTR mitigation_flags = |
+ PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE | |
+ PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE | |
cpu_(ooo_6.6-7.5)
2012/07/02 21:42:32
I think these flags need to be passed as an argume
|
+ PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE; |
+ |
+// TODO(jschuh): Remove this #ifdef after we resolve the SDK versioning. |
+#if defined(_WIN32_WINNT_WIN8) && _WIN32_WINNT >= _WIN32_WINNT_WIN8 |
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8) { |
+ mitigation_flags |= |
+ PROCESS_CREATION_MITIGATION_POLICY_HEAP_TERMINATE_ALWAYS_ON | |
+ PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_ON | |
+ PROCESS_CREATION_MITIGATION_POLICY_HIGH_ENTROPY_ASLR_ALWAYS_ON | |
+ PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON_REQ_RELOCS; |
+ } |
+#endif |
+ |
+ if (startup_info.InitializeProcThreadAttributeList(1)) { |
+ startup_info.UpdateProcThreadAttribute( |
+ PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &mitigation_flags, |
+ sizeof(mitigation_flags)); |
+ } |
} |
base::win::ScopedProcessInformation process_info; |
@@ -161,7 +290,7 @@ |
flags, |
NULL, // Use the environment of the caller. |
NULL, // Use current directory of the caller. |
- &startup_info, |
+ startup_info.data(), |
process_info.Receive())) { |
return ::GetLastError(); |
} |