| 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 "content/common/sandbox_win.h" | 5 #include "content/common/sandbox_win.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 CHECK(::GetTokenInformation(token, TokenSessionId, &session_id, | 242 CHECK(::GetTokenInformation(token, TokenSessionId, &session_id, |
| 243 sizeof(session_id), &session_id_length)); | 243 sizeof(session_id), &session_id_length)); |
| 244 CloseHandle(token); | 244 CloseHandle(token); |
| 245 if (session_id) | 245 if (session_id) |
| 246 s_session_id = session_id; | 246 s_session_id = session_id; |
| 247 } | 247 } |
| 248 | 248 |
| 249 return base::StringPrintf(L"\\Sessions\\%lu%ls", s_session_id, object); | 249 return base::StringPrintf(L"\\Sessions\\%lu%ls", s_session_id, object); |
| 250 } | 250 } |
| 251 | 251 |
| 252 // Checks if the sandbox should be let to run without a job object assigned. | 252 // Checks if the sandbox can be let to run without a job object assigned. |
| 253 // Returns true if the job object has to be applied to the sandbox and false |
| 254 // otherwise. |
| 253 bool ShouldSetJobLevel(const base::CommandLine& cmd_line) { | 255 bool ShouldSetJobLevel(const base::CommandLine& cmd_line) { |
| 254 if (!cmd_line.HasSwitch(switches::kAllowNoSandboxJob)) | |
| 255 return true; | |
| 256 | |
| 257 // Windows 8 allows nested jobs so we don't need to check if we are in other | 256 // Windows 8 allows nested jobs so we don't need to check if we are in other |
| 258 // job. | 257 // job. |
| 259 if (base::win::GetVersion() >= base::win::VERSION_WIN8) | 258 if (base::win::GetVersion() >= base::win::VERSION_WIN8) |
| 260 return true; | 259 return true; |
| 261 | 260 |
| 262 BOOL in_job = true; | 261 BOOL in_job = true; |
| 263 // Either there is no job yet associated so we must add our job, | 262 // Either there is no job yet associated so we must add our job, |
| 264 if (!::IsProcessInJob(::GetCurrentProcess(), NULL, &in_job)) | 263 if (!::IsProcessInJob(::GetCurrentProcess(), NULL, &in_job)) |
| 265 NOTREACHED() << "IsProcessInJob failed. " << GetLastError(); | 264 NOTREACHED() << "IsProcessInJob failed. " << GetLastError(); |
| 266 if (!in_job) | 265 if (!in_job) |
| 267 return true; | 266 return true; |
| 268 | 267 |
| 269 // ...or there is a job but the JOB_OBJECT_LIMIT_BREAKAWAY_OK limit is set. | 268 // ...or there is a job but the JOB_OBJECT_LIMIT_BREAKAWAY_OK limit is set. |
| 270 JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {}; | 269 JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {}; |
| 271 if (!::QueryInformationJobObject(NULL, | 270 if (!::QueryInformationJobObject(NULL, |
| 272 JobObjectExtendedLimitInformation, &job_info, | 271 JobObjectExtendedLimitInformation, &job_info, |
| 273 sizeof(job_info), NULL)) { | 272 sizeof(job_info), NULL)) { |
| 274 NOTREACHED() << "QueryInformationJobObject failed. " << GetLastError(); | 273 NOTREACHED() << "QueryInformationJobObject failed. " << GetLastError(); |
| 275 return true; | 274 return true; |
| 276 } | 275 } |
| 277 if (job_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) | 276 if (job_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) |
| 278 return true; | 277 return true; |
| 279 | 278 |
| 279 // Lastly in place of the flag which was supposed to be used only for running |
| 280 // Chrome in remote sessions we do this check explicitly here. |
| 281 // According to MS this flag can be false for a remote session only on Windows |
| 282 // Server 2012 and newer so if we do the check last we should be on the safe |
| 283 // side. See: https://msdn.microsoft.com/en-us/library/aa380798.aspx. |
| 284 if (!::GetSystemMetrics(SM_REMOTESESSION)) { |
| 285 // Measure how often we would have decided to apply the sandbox but the |
| 286 // user actually wanted to avoid it. |
| 287 // TODO(pastarmovj): Remove this check and the flag altogether once we are |
| 288 // convinced that the automatic logic is good enough. |
| 289 bool set_job = !cmd_line.HasSwitch(switches::kAllowNoSandboxJob); |
| 290 UMA_HISTOGRAM_BOOLEAN("Process.Sandbox.FlagOverrodeRemoteSessionCheck", |
| 291 !set_job); |
| 292 return set_job; |
| 293 } |
| 294 |
| 295 // Allow running without the sandbox in this case. This slightly reduces the |
| 296 // ability of the sandbox to protect its children from spawning new processes |
| 297 // or preventing them from shutting down Windows or accessing the clipboard. |
| 280 return false; | 298 return false; |
| 281 } | 299 } |
| 282 | 300 |
| 283 // Adds the generic policy rules to a sandbox TargetPolicy. | 301 // Adds the generic policy rules to a sandbox TargetPolicy. |
| 284 sandbox::ResultCode AddGenericPolicy(sandbox::TargetPolicy* policy) { | 302 sandbox::ResultCode AddGenericPolicy(sandbox::TargetPolicy* policy) { |
| 285 sandbox::ResultCode result; | 303 sandbox::ResultCode result; |
| 286 | 304 |
| 287 // Add the policy for the client side of a pipe. It is just a file | 305 // Add the policy for the client side of a pipe. It is just a file |
| 288 // in the \pipe\ namespace. We restrict it to pipes that start with | 306 // in the \pipe\ namespace. We restrict it to pipes that start with |
| 289 // "chrome." so the sandboxed process cannot connect to system services. | 307 // "chrome." so the sandboxed process cannot connect to system services. |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 } | 851 } |
| 834 | 852 |
| 835 delegate->PostSpawnTarget(target.process_handle()); | 853 delegate->PostSpawnTarget(target.process_handle()); |
| 836 | 854 |
| 837 CHECK(ResumeThread(target.thread_handle()) != static_cast<DWORD>(-1)); | 855 CHECK(ResumeThread(target.thread_handle()) != static_cast<DWORD>(-1)); |
| 838 *process = base::Process(target.TakeProcessHandle()); | 856 *process = base::Process(target.TakeProcessHandle()); |
| 839 return sandbox::SBOX_ALL_OK; | 857 return sandbox::SBOX_ALL_OK; |
| 840 } | 858 } |
| 841 | 859 |
| 842 } // namespace content | 860 } // namespace content |
| OLD | NEW |