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/target_process.h" | 5 #include "sandbox/win/src/target_process.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/win/pe_image.h" | 9 #include "base/win/pe_image.h" |
10 #include "base/win/startup_information.h" | 10 #include "base/win/startup_information.h" |
11 #include "base/win/windows_version.h" | 11 #include "base/win/windows_version.h" |
12 #include "sandbox/win/src/crosscall_server.h" | 12 #include "sandbox/win/src/crosscall_server.h" |
13 #include "sandbox/win/src/crosscall_client.h" | 13 #include "sandbox/win/src/crosscall_client.h" |
14 #include "sandbox/win/src/policy_low_level.h" | 14 #include "sandbox/win/src/policy_low_level.h" |
15 #include "sandbox/win/src/sandbox_types.h" | 15 #include "sandbox/win/src/sandbox_types.h" |
16 #include "sandbox/win/src/sharedmem_ipc_server.h" | 16 #include "sandbox/win/src/sharedmem_ipc_server.h" |
17 #include "sandbox/win/src/win_utils.h" | |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
20 void CopyPolicyToTarget(const void* source, size_t size, void* dest) { | 21 void CopyPolicyToTarget(const void* source, size_t size, void* dest) { |
21 if (!source || !size) | 22 if (!source || !size) |
22 return; | 23 return; |
23 memcpy(dest, source, size); | 24 memcpy(dest, source, size); |
24 sandbox::PolicyGlobal* policy = | 25 sandbox::PolicyGlobal* policy = |
25 reinterpret_cast<sandbox::PolicyGlobal*>(dest); | 26 reinterpret_cast<sandbox::PolicyGlobal*>(dest); |
26 | 27 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 | 127 |
127 if (startup_info.has_extended_startup_info()) | 128 if (startup_info.has_extended_startup_info()) |
128 flags |= EXTENDED_STARTUPINFO_PRESENT; | 129 flags |= EXTENDED_STARTUPINFO_PRESENT; |
129 | 130 |
130 if (job_ && base::win::GetVersion() < base::win::VERSION_WIN8) { | 131 if (job_ && base::win::GetVersion() < base::win::VERSION_WIN8) { |
131 // Windows 8 implements nested jobs, but for older systems we need to | 132 // Windows 8 implements nested jobs, but for older systems we need to |
132 // break out of any job we're in to enforce our restrictions. | 133 // break out of any job we're in to enforce our restrictions. |
133 flags |= CREATE_BREAKAWAY_FROM_JOB; | 134 flags |= CREATE_BREAKAWAY_FROM_JOB; |
134 } | 135 } |
135 | 136 |
137 base::win::ScopedHandle scoped_lockdown_token(lockdown_token_.Take()); | |
136 PROCESS_INFORMATION temp_process_info = {}; | 138 PROCESS_INFORMATION temp_process_info = {}; |
137 if (!::CreateProcessAsUserW(lockdown_token_.Get(), | 139 if (base::win::GetVersion() < base::win::VERSION_WIN8) { |
138 exe_path, | 140 if (!::CreateProcessAsUserW(scoped_lockdown_token.Get(), |
139 cmd_line.get(), | 141 exe_path, |
140 NULL, // No security attribute. | 142 cmd_line.get(), |
141 NULL, // No thread attribute. | 143 NULL, // No security attribute. |
142 inherit_handles, | 144 NULL, // No thread attribute. |
143 flags, | 145 inherit_handles, |
144 NULL, // Use the environment of the caller. | 146 flags, |
145 NULL, // Use current directory of the caller. | 147 NULL, // Use the environment of the caller. |
146 startup_info.startup_info(), | 148 NULL, // Use current directory of the caller. |
147 &temp_process_info)) { | 149 startup_info.startup_info(), |
148 return ::GetLastError(); | 150 &temp_process_info)) { |
151 return ::GetLastError(); | |
152 } | |
153 } else { | |
154 // For Windows 8 and above we will first create process with a default token | |
155 // and then replace it later, after setting primary thread token. This is | |
156 // required for setting an appcontainer token along with an impersonation | |
157 // token. | |
158 if (!::CreateProcess(exe_path, | |
159 cmd_line.get(), | |
Will Harris
2015/02/21 02:45:45
nit: align parameters
Shrikant Kelkar
2015/02/21 03:14:41
Done.
| |
160 NULL, // No security attribute. | |
161 NULL, // No thread attribute. | |
162 inherit_handles, | |
163 flags, | |
164 NULL, // Use the environment of the caller. | |
165 NULL, // Use current directory of the caller. | |
166 startup_info.startup_info(), | |
167 &temp_process_info)) { | |
168 return ::GetLastError(); | |
169 } | |
149 } | 170 } |
150 base::win::ScopedProcessInformation process_info(temp_process_info); | 171 base::win::ScopedProcessInformation process_info(temp_process_info); |
151 lockdown_token_.Close(); | |
152 | 172 |
153 DWORD win_result = ERROR_SUCCESS; | 173 DWORD win_result = ERROR_SUCCESS; |
154 | 174 |
155 if (job_) { | 175 if (job_) { |
156 // Assign the suspended target to the windows job object. | 176 // Assign the suspended target to the windows job object. |
157 if (!::AssignProcessToJobObject(job_, process_info.process_handle())) { | 177 if (!::AssignProcessToJobObject(job_, process_info.process_handle())) { |
158 win_result = ::GetLastError(); | 178 win_result = ::GetLastError(); |
159 ::TerminateProcess(process_info.process_handle(), 0); | 179 ::TerminateProcess(process_info.process_handle(), 0); |
160 return win_result; | 180 return win_result; |
161 } | 181 } |
162 } | 182 } |
163 | 183 |
164 if (initial_token_.IsValid()) { | 184 if (initial_token_.IsValid()) { |
165 // Change the token of the main thread of the new process for the | 185 // Change the token of the main thread of the new process for the |
166 // impersonation token with more rights. This allows the target to start; | 186 // impersonation token with more rights. This allows the target to start; |
167 // otherwise it will crash too early for us to help. | 187 // otherwise it will crash too early for us to help. |
168 HANDLE temp_thread = process_info.thread_handle(); | 188 HANDLE temp_thread = process_info.thread_handle(); |
169 if (!::SetThreadToken(&temp_thread, initial_token_.Get())) { | 189 if (!::SetThreadToken(&temp_thread, initial_token_.Get())) { |
170 win_result = ::GetLastError(); | 190 win_result = ::GetLastError(); |
171 // It might be a security breach if we let the target run outside the job | 191 // It might be a security breach if we let the target run outside the job |
172 // so kill it before it causes damage. | 192 // so kill it before it causes damage. |
173 ::TerminateProcess(process_info.process_handle(), 0); | 193 ::TerminateProcess(process_info.process_handle(), 0); |
174 return win_result; | 194 return win_result; |
175 } | 195 } |
176 initial_token_.Close(); | 196 initial_token_.Close(); |
177 } | 197 } |
178 | 198 |
199 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | |
200 PROCESS_ACCESS_TOKEN process_access_token; | |
201 process_access_token.thread = process_info.thread_handle(); | |
202 process_access_token.token = scoped_lockdown_token.Get(); | |
203 | |
204 NtSetInformationProcess SetInformationProcess = NULL; | |
205 ResolveNTFunctionPtr("NtSetInformationProcess", &SetInformationProcess); | |
206 | |
207 NTSTATUS status = SetInformationProcess( | |
208 process_info.process_handle(), | |
209 static_cast<PROCESS_INFORMATION_CLASS>(NtProcessInformationAccessToken), | |
210 &process_access_token, | |
211 sizeof(process_access_token)); | |
212 if (!NT_SUCCESS(status)) { | |
213 win_result = ::GetLastError(); | |
214 ::TerminateProcess(process_info.process_handle(), 0); // exit code | |
215 return win_result; | |
216 } | |
217 } | |
218 | |
179 CONTEXT context; | 219 CONTEXT context; |
180 context.ContextFlags = CONTEXT_ALL; | 220 context.ContextFlags = CONTEXT_ALL; |
181 if (!::GetThreadContext(process_info.thread_handle(), &context)) { | 221 if (!::GetThreadContext(process_info.thread_handle(), &context)) { |
182 win_result = ::GetLastError(); | 222 win_result = ::GetLastError(); |
183 ::TerminateProcess(process_info.process_handle(), 0); | 223 ::TerminateProcess(process_info.process_handle(), 0); |
184 return win_result; | 224 return win_result; |
185 } | 225 } |
186 | 226 |
187 #if defined(_WIN64) | 227 #if defined(_WIN64) |
188 void* entry_point = reinterpret_cast<void*>(context.Rcx); | 228 void* entry_point = reinterpret_cast<void*>(context.Rcx); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) { | 370 TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) { |
331 TargetProcess* target = new TargetProcess(NULL, NULL, NULL, NULL); | 371 TargetProcess* target = new TargetProcess(NULL, NULL, NULL, NULL); |
332 PROCESS_INFORMATION process_info = {}; | 372 PROCESS_INFORMATION process_info = {}; |
333 process_info.hProcess = process; | 373 process_info.hProcess = process; |
334 target->sandbox_process_info_.Set(process_info); | 374 target->sandbox_process_info_.Set(process_info); |
335 target->base_address_ = base_address; | 375 target->base_address_ = base_address; |
336 return target; | 376 return target; |
337 } | 377 } |
338 | 378 |
339 } // namespace sandbox | 379 } // namespace sandbox |
OLD | NEW |