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

Side by Side Diff: sandbox/win/src/sandbox_policy_base.cc

Issue 937353002: Adding method to create process using LowBox token in sandbox code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review changes.. Created 5 years, 9 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
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/sandbox_policy_base.h" 5 #include "sandbox/win/src/sandbox_policy_base.h"
6 6
7 #include <sddl.h> 7 #include <sddl.h>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 use_alternate_winstation_(false), 91 use_alternate_winstation_(false),
92 file_system_init_(false), 92 file_system_init_(false),
93 relaxed_interceptions_(true), 93 relaxed_interceptions_(true),
94 stdout_handle_(INVALID_HANDLE_VALUE), 94 stdout_handle_(INVALID_HANDLE_VALUE),
95 stderr_handle_(INVALID_HANDLE_VALUE), 95 stderr_handle_(INVALID_HANDLE_VALUE),
96 integrity_level_(INTEGRITY_LEVEL_LAST), 96 integrity_level_(INTEGRITY_LEVEL_LAST),
97 delayed_integrity_level_(INTEGRITY_LEVEL_LAST), 97 delayed_integrity_level_(INTEGRITY_LEVEL_LAST),
98 mitigations_(0), 98 mitigations_(0),
99 delayed_mitigations_(0), 99 delayed_mitigations_(0),
100 policy_maker_(NULL), 100 policy_maker_(NULL),
101 policy_(NULL) { 101 policy_(NULL),
102 lowbox_sid_(NULL) {
102 ::InitializeCriticalSection(&lock_); 103 ::InitializeCriticalSection(&lock_);
103 // Initialize the IPC dispatcher array. 104 // Initialize the IPC dispatcher array.
104 memset(&ipc_targets_, NULL, sizeof(ipc_targets_)); 105 memset(&ipc_targets_, NULL, sizeof(ipc_targets_));
105 Dispatcher* dispatcher = NULL; 106 Dispatcher* dispatcher = NULL;
106 107
107 dispatcher = new FilesystemDispatcher(this); 108 dispatcher = new FilesystemDispatcher(this);
108 ipc_targets_[IPC_NTCREATEFILE_TAG] = dispatcher; 109 ipc_targets_[IPC_NTCREATEFILE_TAG] = dispatcher;
109 ipc_targets_[IPC_NTOPENFILE_TAG] = dispatcher; 110 ipc_targets_[IPC_NTOPENFILE_TAG] = dispatcher;
110 ipc_targets_[IPC_NTSETINFO_RENAME_TAG] = dispatcher; 111 ipc_targets_[IPC_NTSETINFO_RENAME_TAG] = dispatcher;
111 ipc_targets_[IPC_NTQUERYATTRIBUTESFILE_TAG] = dispatcher; 112 ipc_targets_[IPC_NTQUERYATTRIBUTESFILE_TAG] = dispatcher;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 delete target; 146 delete target;
146 } 147 }
147 delete ipc_targets_[IPC_NTCREATEFILE_TAG]; 148 delete ipc_targets_[IPC_NTCREATEFILE_TAG];
148 delete ipc_targets_[IPC_CREATENAMEDPIPEW_TAG]; 149 delete ipc_targets_[IPC_CREATENAMEDPIPEW_TAG];
149 delete ipc_targets_[IPC_NTOPENTHREAD_TAG]; 150 delete ipc_targets_[IPC_NTOPENTHREAD_TAG];
150 delete ipc_targets_[IPC_CREATEEVENT_TAG]; 151 delete ipc_targets_[IPC_CREATEEVENT_TAG];
151 delete ipc_targets_[IPC_NTCREATEKEY_TAG]; 152 delete ipc_targets_[IPC_NTCREATEKEY_TAG];
152 delete ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG]; 153 delete ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG];
153 delete policy_maker_; 154 delete policy_maker_;
154 delete policy_; 155 delete policy_;
156
157 if (lowbox_sid_)
158 ::LocalFree(lowbox_sid_);
159
155 ::DeleteCriticalSection(&lock_); 160 ::DeleteCriticalSection(&lock_);
156 } 161 }
157 162
158 void PolicyBase::AddRef() { 163 void PolicyBase::AddRef() {
159 ::InterlockedIncrement(&ref_count); 164 ::InterlockedIncrement(&ref_count);
160 } 165 }
161 166
162 void PolicyBase::Release() { 167 void PolicyBase::Release() {
163 if (0 == ::InterlockedDecrement(&ref_count)) 168 if (0 == ::InterlockedDecrement(&ref_count))
164 delete this; 169 delete this;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 ResultCode PolicyBase::SetDelayedIntegrityLevel( 308 ResultCode PolicyBase::SetDelayedIntegrityLevel(
304 IntegrityLevel integrity_level) { 309 IntegrityLevel integrity_level) {
305 delayed_integrity_level_ = integrity_level; 310 delayed_integrity_level_ = integrity_level;
306 return SBOX_ALL_OK; 311 return SBOX_ALL_OK;
307 } 312 }
308 313
309 ResultCode PolicyBase::SetAppContainer(const wchar_t* sid) { 314 ResultCode PolicyBase::SetAppContainer(const wchar_t* sid) {
310 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) 315 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8)
311 return SBOX_ALL_OK; 316 return SBOX_ALL_OK;
312 317
318 // SetLowBox and SetAppContainer are mutually exclusive.
319 if (lowbox_sid_)
320 return SBOX_ERROR_UNSUPPORTED;
321
313 // Windows refuses to work with an impersonation token for a process inside 322 // Windows refuses to work with an impersonation token for a process inside
314 // an AppContainer. If the caller wants to use a more privileged initial 323 // an AppContainer. If the caller wants to use a more privileged initial
315 // token, or if the lockdown level will prevent the process from starting, 324 // token, or if the lockdown level will prevent the process from starting,
316 // we have to fail the operation. 325 // we have to fail the operation.
317 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) 326 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_)
318 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; 327 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER;
319 328
320 DCHECK(!appcontainer_list_.get()); 329 DCHECK(!appcontainer_list_.get());
321 appcontainer_list_.reset(new AppContainerAttributes); 330 appcontainer_list_.reset(new AppContainerAttributes);
322 ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_); 331 ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_);
323 if (rv != SBOX_ALL_OK) 332 if (rv != SBOX_ALL_OK)
324 return rv; 333 return rv;
325 334
326 return SBOX_ALL_OK; 335 return SBOX_ALL_OK;
327 } 336 }
328 337
329 ResultCode PolicyBase::SetCapability(const wchar_t* sid) { 338 ResultCode PolicyBase::SetCapability(const wchar_t* sid) {
330 capabilities_.push_back(sid); 339 capabilities_.push_back(sid);
331 return SBOX_ALL_OK; 340 return SBOX_ALL_OK;
332 } 341 }
333 342
343 ResultCode PolicyBase::SetLowBox(const wchar_t* sid) {
344 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8)
345 return SBOX_ERROR_UNSUPPORTED;
rvargas (doing something else) 2015/02/28 02:48:05 This is now inconsistent.
Shrikant Kelkar 2015/03/01 00:31:43 Let's discuss Monday.
346
347 // SetLowBox and SetAppContainer are mutually exclusive.
348 if (appcontainer_list_.get())
349 return SBOX_ERROR_UNSUPPORTED;
350
351 DCHECK(sid);
352
353 if (lowbox_sid_)
354 return SBOX_ERROR_BAD_PARAMS;
355
356 if (!ConvertStringSidToSid(sid, &lowbox_sid_))
357 return SBOX_ERROR_GENERIC;
358
359 return SBOX_ALL_OK;
360 }
361
334 ResultCode PolicyBase::SetProcessMitigations( 362 ResultCode PolicyBase::SetProcessMitigations(
335 MitigationFlags flags) { 363 MitigationFlags flags) {
336 if (!CanSetProcessMitigationsPreStartup(flags)) 364 if (!CanSetProcessMitigationsPreStartup(flags))
337 return SBOX_ERROR_BAD_PARAMS; 365 return SBOX_ERROR_BAD_PARAMS;
338 mitigations_ = flags; 366 mitigations_ = flags;
339 return SBOX_ALL_OK; 367 return SBOX_ALL_OK;
340 } 368 }
341 369
342 MitigationFlags PolicyBase::GetProcessMitigations() { 370 MitigationFlags PolicyBase::GetProcessMitigations() {
343 return mitigations_; 371 return mitigations_;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 return SBOX_ERROR_GENERIC; 469 return SBOX_ERROR_GENERIC;
442 } 470 }
443 *job = job_obj.Detach(); 471 *job = job_obj.Detach();
444 } else { 472 } else {
445 *job = NULL; 473 *job = NULL;
446 } 474 }
447 return SBOX_ALL_OK; 475 return SBOX_ALL_OK;
448 } 476 }
449 477
450 ResultCode PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { 478 ResultCode PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) {
479 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer() &&
480 lowbox_sid_) {
481 return SBOX_ERROR_BAD_PARAMS;
482 }
483
451 // Create the 'naked' token. This will be the permanent token associated 484 // Create the 'naked' token. This will be the permanent token associated
452 // with the process and therefore with any thread that is not impersonating. 485 // with the process and therefore with any thread that is not impersonating.
453 DWORD result = CreateRestrictedToken(lockdown, lockdown_level_, 486 DWORD result = CreateRestrictedToken(lockdown, lockdown_level_,
454 integrity_level_, PRIMARY); 487 integrity_level_, PRIMARY);
455 if (ERROR_SUCCESS != result) 488 if (ERROR_SUCCESS != result)
456 return SBOX_ERROR_GENERIC; 489 return SBOX_ERROR_GENERIC;
457 490
458 // If we're launching on the alternate desktop we need to make sure the 491 // If we're launching on the alternate desktop we need to make sure the
459 // integrity label on the object is no higher than the sandboxed process's 492 // integrity label on the object is no higher than the sandboxed process's
460 // integrity level. So, we lower the label on the desktop process if it's 493 // integrity level. So, we lower the label on the desktop process if it's
461 // not already low enough for our process. 494 // not already low enough for our process.
462 if (alternate_desktop_handle_ && use_alternate_desktop_ && 495 if (alternate_desktop_handle_ && use_alternate_desktop_ &&
463 integrity_level_ != INTEGRITY_LEVEL_LAST && 496 integrity_level_ != INTEGRITY_LEVEL_LAST &&
464 alternate_desktop_integrity_level_label_ < integrity_level_ && 497 alternate_desktop_integrity_level_label_ < integrity_level_ &&
465 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { 498 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) {
466 // Integrity label enum is reversed (higher level is a lower value). 499 // Integrity label enum is reversed (higher level is a lower value).
467 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, 500 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED,
468 "Integrity level ordering reversed."); 501 "Integrity level ordering reversed.");
469 result = SetObjectIntegrityLabel(alternate_desktop_handle_, 502 result = SetObjectIntegrityLabel(alternate_desktop_handle_,
470 SE_WINDOW_OBJECT, 503 SE_WINDOW_OBJECT,
471 L"", 504 L"",
472 GetIntegrityLevelString(integrity_level_)); 505 GetIntegrityLevelString(integrity_level_));
473 if (ERROR_SUCCESS != result) 506 if (ERROR_SUCCESS != result)
474 return SBOX_ERROR_GENERIC; 507 return SBOX_ERROR_GENERIC;
475 508
476 alternate_desktop_integrity_level_label_ = integrity_level_; 509 alternate_desktop_integrity_level_label_ = integrity_level_;
477 } 510 }
478 511
512 // We are maintaining two mutually exclusive approaches. One is to start an
513 // AppContainer process through StartupInfoEx and other is replacing
514 // existing token with LowBox token after process creation.
479 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { 515 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) {
480 // Windows refuses to work with an impersonation token. See SetAppContainer 516 // Windows refuses to work with an impersonation token. See SetAppContainer
481 // implementation for more details. 517 // implementation for more details.
482 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) 518 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_)
483 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; 519 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER;
484 520
485 *initial = INVALID_HANDLE_VALUE; 521 *initial = INVALID_HANDLE_VALUE;
486 return SBOX_ALL_OK; 522 return SBOX_ALL_OK;
523 } else if (lowbox_sid_) {
524 NtCreateLowBoxToken CreateLowBoxToken = NULL;
525 ResolveNTFunctionPtr("NtCreateLowBoxToken", &CreateLowBoxToken);
526 OBJECT_ATTRIBUTES obj_attr;
527 InitializeObjectAttributes(&obj_attr, NULL, 0, NULL, NULL);
528 HANDLE token_lowbox = NULL;
529
530 NTSTATUS status = CreateLowBoxToken(&token_lowbox, *lockdown,
531 TOKEN_ALL_ACCESS, &obj_attr,
532 lowbox_sid_, 0, NULL, 0, NULL);
533 if (!NT_SUCCESS(status))
534 return SBOX_ERROR_GENERIC;
535
536 DCHECK(token_lowbox);
537 ::CloseHandle(*lockdown);
538 *lockdown = token_lowbox;
487 } 539 }
488 540
489 // Create the 'better' token. We use this token as the one that the main 541 // Create the 'better' token. We use this token as the one that the main
490 // thread uses when booting up the process. It should contain most of 542 // thread uses when booting up the process. It should contain most of
491 // what we need (before reaching main( )) 543 // what we need (before reaching main( ))
492 result = CreateRestrictedToken(initial, initial_level_, 544 result = CreateRestrictedToken(initial, initial_level_,
493 integrity_level_, IMPERSONATION); 545 integrity_level_, IMPERSONATION);
494 if (ERROR_SUCCESS != result) { 546 if (ERROR_SUCCESS != result) {
495 ::CloseHandle(*lockdown); 547 ::CloseHandle(*lockdown);
496 return SBOX_ERROR_GENERIC; 548 return SBOX_ERROR_GENERIC;
497 } 549 }
498 return SBOX_ALL_OK; 550 return SBOX_ALL_OK;
499 } 551 }
500 552
501 const AppContainerAttributes* PolicyBase::GetAppContainer() const { 553 const AppContainerAttributes* PolicyBase::GetAppContainer() const {
502 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) 554 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer())
503 return NULL; 555 return NULL;
504 556
505 return appcontainer_list_.get(); 557 return appcontainer_list_.get();
506 } 558 }
507 559
560 const PSID PolicyBase::GetLowBoxSid() const {
561 return lowbox_sid_;
562 }
563
508 bool PolicyBase::AddTarget(TargetProcess* target) { 564 bool PolicyBase::AddTarget(TargetProcess* target) {
509 if (NULL != policy_) 565 if (NULL != policy_)
510 policy_maker_->Done(); 566 policy_maker_->Done();
511 567
512 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(), 568 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(),
513 mitigations_)) { 569 mitigations_)) {
514 return false; 570 return false;
515 } 571 }
516 572
517 if (!SetupAllInterceptions(target)) 573 if (!SetupAllInterceptions(target))
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 break; 796 break;
741 } 797 }
742 798
743 default: { return SBOX_ERROR_UNSUPPORTED; } 799 default: { return SBOX_ERROR_UNSUPPORTED; }
744 } 800 }
745 801
746 return SBOX_ALL_OK; 802 return SBOX_ALL_OK;
747 } 803 }
748 804
749 } // namespace sandbox 805 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698