security/sandbox/win/src/sandbox_policy_base.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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
     3 // found in the LICENSE file.
     5 #include "sandbox/win/src/sandbox_policy_base.h"
     7 #include "base/basictypes.h"
     8 #include "base/callback.h"
     9 #include "base/logging.h"
    10 #include "base/win/windows_version.h"
    11 #include "sandbox/win/src/app_container.h"
    12 #include "sandbox/win/src/filesystem_dispatcher.h"
    13 #include "sandbox/win/src/filesystem_policy.h"
    14 #include "sandbox/win/src/handle_dispatcher.h"
    15 #include "sandbox/win/src/handle_policy.h"
    16 #include "sandbox/win/src/job.h"
    17 #include "sandbox/win/src/interception.h"
    18 #include "sandbox/win/src/process_mitigations.h"
    19 #include "sandbox/win/src/named_pipe_dispatcher.h"
    20 #include "sandbox/win/src/named_pipe_policy.h"
    21 #include "sandbox/win/src/policy_broker.h"
    22 #include "sandbox/win/src/policy_engine_processor.h"
    23 #include "sandbox/win/src/policy_low_level.h"
    24 #include "sandbox/win/src/process_thread_dispatcher.h"
    25 #include "sandbox/win/src/process_thread_policy.h"
    26 #include "sandbox/win/src/registry_dispatcher.h"
    27 #include "sandbox/win/src/registry_policy.h"
    28 #include "sandbox/win/src/restricted_token_utils.h"
    29 #include "sandbox/win/src/sandbox_policy.h"
    30 #include "sandbox/win/src/sync_dispatcher.h"
    31 #include "sandbox/win/src/sync_policy.h"
    32 #include "sandbox/win/src/target_process.h"
    33 #include "sandbox/win/src/window.h"
    35 namespace {
    37 // The standard windows size for one memory page.
    38 const size_t kOneMemPage = 4096;
    39 // The IPC and Policy shared memory sizes.
    40 const size_t kIPCMemSize = kOneMemPage * 2;
    41 const size_t kPolMemSize = kOneMemPage * 14;
    43 // Helper function to allocate space (on the heap) for policy.
    44 sandbox::PolicyGlobal* MakeBrokerPolicyMemory() {
    45   const size_t kTotalPolicySz = kPolMemSize;
    46   sandbox::PolicyGlobal* policy = static_cast<sandbox::PolicyGlobal*>
    47       (::operator new(kTotalPolicySz));
    48   DCHECK(policy);
    49   memset(policy, 0, kTotalPolicySz);
    50   policy->data_size = kTotalPolicySz - sizeof(sandbox::PolicyGlobal);
    51   return policy;
    52 }
    54 bool IsInheritableHandle(HANDLE handle) {
    55   if (!handle)
    56     return false;
    57   if (handle == INVALID_HANDLE_VALUE)
    58     return false;
    59   // File handles (FILE_TYPE_DISK) and pipe handles are known to be
    60   // inheritable.  Console handles (FILE_TYPE_CHAR) are not
    61   // inheritable via PROC_THREAD_ATTRIBUTE_HANDLE_LIST.
    62   DWORD handle_type = GetFileType(handle);
    63   return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE;
    64 }
    66 }
    68 namespace sandbox {
    70 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level;
    71 SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations;
    73 // Initializes static members.
    74 HWINSTA PolicyBase::alternate_winstation_handle_ = NULL;
    75 HDESK PolicyBase::alternate_desktop_handle_ = NULL;
    77 PolicyBase::PolicyBase()
    78     : ref_count(1),
    79       lockdown_level_(USER_LOCKDOWN),
    80       initial_level_(USER_LOCKDOWN),
    81       job_level_(JOB_LOCKDOWN),
    82       ui_exceptions_(0),
    83       use_alternate_desktop_(false),
    84       use_alternate_winstation_(false),
    85       file_system_init_(false),
    86       relaxed_interceptions_(true),
    87       stdout_handle_(INVALID_HANDLE_VALUE),
    88       stderr_handle_(INVALID_HANDLE_VALUE),
    89       integrity_level_(INTEGRITY_LEVEL_LAST),
    90       delayed_integrity_level_(INTEGRITY_LEVEL_LAST),
    91       mitigations_(0),
    92       delayed_mitigations_(0),
    93       policy_maker_(NULL),
    94       policy_(NULL) {
    95   ::InitializeCriticalSection(&lock_);
    96   // Initialize the IPC dispatcher array.
    97   memset(&ipc_targets_, NULL, sizeof(ipc_targets_));
    98   Dispatcher* dispatcher = NULL;
   100   dispatcher = new FilesystemDispatcher(this);
   101   ipc_targets_[IPC_NTCREATEFILE_TAG] = dispatcher;
   102   ipc_targets_[IPC_NTOPENFILE_TAG] = dispatcher;
   103   ipc_targets_[IPC_NTSETINFO_RENAME_TAG] = dispatcher;
   104   ipc_targets_[IPC_NTQUERYATTRIBUTESFILE_TAG] = dispatcher;
   105   ipc_targets_[IPC_NTQUERYFULLATTRIBUTESFILE_TAG] = dispatcher;
   107   dispatcher = new NamedPipeDispatcher(this);
   108   ipc_targets_[IPC_CREATENAMEDPIPEW_TAG] = dispatcher;
   110   dispatcher = new ThreadProcessDispatcher(this);
   111   ipc_targets_[IPC_NTOPENTHREAD_TAG] = dispatcher;
   112   ipc_targets_[IPC_NTOPENPROCESS_TAG] = dispatcher;
   113   ipc_targets_[IPC_CREATEPROCESSW_TAG] = dispatcher;
   114   ipc_targets_[IPC_NTOPENPROCESSTOKEN_TAG] = dispatcher;
   115   ipc_targets_[IPC_NTOPENPROCESSTOKENEX_TAG] = dispatcher;
   117   dispatcher = new SyncDispatcher(this);
   118   ipc_targets_[IPC_CREATEEVENT_TAG] = dispatcher;
   119   ipc_targets_[IPC_OPENEVENT_TAG] = dispatcher;
   121   dispatcher = new RegistryDispatcher(this);
   122   ipc_targets_[IPC_NTCREATEKEY_TAG] = dispatcher;
   123   ipc_targets_[IPC_NTOPENKEY_TAG] = dispatcher;
   125   dispatcher = new HandleDispatcher(this);
   126   ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG] = dispatcher;
   127 }
   129 PolicyBase::~PolicyBase() {
   130   TargetSet::iterator it;
   131   for (it = targets_.begin(); it != targets_.end(); ++it) {
   132     TargetProcess* target = (*it);
   133     delete target;
   134   }
   135   delete ipc_targets_[IPC_NTCREATEFILE_TAG];
   136   delete ipc_targets_[IPC_CREATENAMEDPIPEW_TAG];
   137   delete ipc_targets_[IPC_NTOPENTHREAD_TAG];
   138   delete ipc_targets_[IPC_CREATEEVENT_TAG];
   139   delete ipc_targets_[IPC_NTCREATEKEY_TAG];
   140   delete ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG];
   141   delete policy_maker_;
   142   delete policy_;
   143   ::DeleteCriticalSection(&lock_);
   144 }
   146 void PolicyBase::AddRef() {
   147   ::InterlockedIncrement(&ref_count);
   148 }
   150 void PolicyBase::Release() {
   151   if (0 == ::InterlockedDecrement(&ref_count))
   152     delete this;
   153 }
   155 ResultCode PolicyBase::SetTokenLevel(TokenLevel initial, TokenLevel lockdown) {
   156   if (initial < lockdown) {
   157     return SBOX_ERROR_BAD_PARAMS;
   158   }
   159   initial_level_ = initial;
   160   lockdown_level_ = lockdown;
   161   return SBOX_ALL_OK;
   162 }
   164 ResultCode PolicyBase::SetJobLevel(JobLevel job_level, uint32 ui_exceptions) {
   165   job_level_ = job_level;
   166   ui_exceptions_ = ui_exceptions;
   167   return SBOX_ALL_OK;
   168 }
   170 ResultCode PolicyBase::SetAlternateDesktop(bool alternate_winstation) {
   171   use_alternate_desktop_ = true;
   172   use_alternate_winstation_ = alternate_winstation;
   173   return CreateAlternateDesktop(alternate_winstation);
   174 }
   176 string16 PolicyBase::GetAlternateDesktop() const {
   177   // No alternate desktop or winstation. Return an empty string.
   178   if (!use_alternate_desktop_ && !use_alternate_winstation_) {
   179     return string16();
   180   }
   182   // The desktop and winstation should have been created by now.
   183   // If we hit this scenario, it means that the user ignored the failure
   184   // during SetAlternateDesktop, so we ignore it here too.
   185   if (use_alternate_desktop_ && !alternate_desktop_handle_) {
   186     return string16();
   187   }
   188   if (use_alternate_winstation_ && (!alternate_desktop_handle_ ||
   189                                     !alternate_winstation_handle_)) {
   190     return string16();
   191   }
   193   return GetFullDesktopName(alternate_winstation_handle_,
   194                             alternate_desktop_handle_);
   195 }
   197 ResultCode PolicyBase::CreateAlternateDesktop(bool alternate_winstation) {
   198   if (alternate_winstation) {
   199     // Previously called with alternate_winstation = false?
   200     if (!alternate_winstation_handle_ && alternate_desktop_handle_)
   201       return SBOX_ERROR_UNSUPPORTED;
   203     // Check if it's already created.
   204     if (alternate_winstation_handle_ && alternate_desktop_handle_)
   205       return SBOX_ALL_OK;
   207     DCHECK(!alternate_winstation_handle_);
   208     // Create the window station.
   209     ResultCode result = CreateAltWindowStation(&alternate_winstation_handle_);
   210     if (SBOX_ALL_OK != result)
   211       return result;
   213     // Verify that everything is fine.
   214     if (!alternate_winstation_handle_ ||
   215         GetWindowObjectName(alternate_winstation_handle_).empty())
   216       return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
   218     // Create the destkop.
   219     result = CreateAltDesktop(alternate_winstation_handle_,
   220                               &alternate_desktop_handle_);
   221     if (SBOX_ALL_OK != result)
   222       return result;
   224     // Verify that everything is fine.
   225     if (!alternate_desktop_handle_ ||
   226         GetWindowObjectName(alternate_desktop_handle_).empty())
   227       return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
   228   } else {
   229     // Previously called with alternate_winstation = true?
   230     if (alternate_winstation_handle_)
   231       return SBOX_ERROR_UNSUPPORTED;
   233     // Check if it already exists.
   234     if (alternate_desktop_handle_)
   235       return SBOX_ALL_OK;
   237     // Create the destkop.
   238     ResultCode result = CreateAltDesktop(NULL, &alternate_desktop_handle_);
   239     if (SBOX_ALL_OK != result)
   240       return result;
   242     // Verify that everything is fine.
   243     if (!alternate_desktop_handle_ ||
   244         GetWindowObjectName(alternate_desktop_handle_).empty())
   245       return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
   246   }
   248   return SBOX_ALL_OK;
   249 }
   251 void PolicyBase::DestroyAlternateDesktop() {
   252   if (alternate_desktop_handle_) {
   253     ::CloseDesktop(alternate_desktop_handle_);
   254     alternate_desktop_handle_ = NULL;
   255   }
   257   if (alternate_winstation_handle_) {
   258     ::CloseWindowStation(alternate_winstation_handle_);
   259     alternate_winstation_handle_ = NULL;
   260   }
   261 }
   263 ResultCode PolicyBase::SetIntegrityLevel(IntegrityLevel integrity_level) {
   264   integrity_level_ = integrity_level;
   265   return SBOX_ALL_OK;
   266 }
   268 ResultCode PolicyBase::SetDelayedIntegrityLevel(
   269     IntegrityLevel integrity_level) {
   270   delayed_integrity_level_ = integrity_level;
   271   return SBOX_ALL_OK;
   272 }
   274 ResultCode PolicyBase::SetAppContainer(const wchar_t* sid) {
   275   if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8)
   276     return SBOX_ALL_OK;
   278   // Windows refuses to work with an impersonation token for a process inside
   279   // an AppContainer. If the caller wants to use a more privileged initial
   280   // token, or if the lockdown level will prevent the process from starting,
   281   // we have to fail the operation.
   282   if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_)
   283     return SBOX_ERROR_CANNOT_INIT_APPCONTAINER;
   285   DCHECK(!appcontainer_list_.get());
   286   appcontainer_list_.reset(new AppContainerAttributes);
   287   ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_);
   288   if (rv != SBOX_ALL_OK)
   289     return rv;
   291   return SBOX_ALL_OK;
   292 }
   294 ResultCode PolicyBase::SetCapability(const wchar_t* sid) {
   295   capabilities_.push_back(sid);
   296   return SBOX_ALL_OK;
   297 }
   299 ResultCode PolicyBase::SetProcessMitigations(
   300     MitigationFlags flags) {
   301   if (!CanSetProcessMitigationsPreStartup(flags))
   302     return SBOX_ERROR_BAD_PARAMS;
   303   mitigations_ = flags;
   304   return SBOX_ALL_OK;
   305 }
   307 MitigationFlags PolicyBase::GetProcessMitigations() {
   308   return mitigations_;
   309 }
   311 ResultCode PolicyBase::SetDelayedProcessMitigations(
   312     MitigationFlags flags) {
   313   if (!CanSetProcessMitigationsPostStartup(flags))
   314     return SBOX_ERROR_BAD_PARAMS;
   315   delayed_mitigations_ = flags;
   316   return SBOX_ALL_OK;
   317 }
   319 MitigationFlags PolicyBase::GetDelayedProcessMitigations() {
   320   return delayed_mitigations_;
   321 }
   323 void PolicyBase::SetStrictInterceptions() {
   324   relaxed_interceptions_ = false;
   325 }
   327 ResultCode PolicyBase::SetStdoutHandle(HANDLE handle) {
   328   if (!IsInheritableHandle(handle))
   329     return SBOX_ERROR_BAD_PARAMS;
   330   stdout_handle_ = handle;
   331   return SBOX_ALL_OK;
   332 }
   334 ResultCode PolicyBase::SetStderrHandle(HANDLE handle) {
   335   if (!IsInheritableHandle(handle))
   336     return SBOX_ERROR_BAD_PARAMS;
   337   stderr_handle_ = handle;
   338   return SBOX_ALL_OK;
   339 }
   341 ResultCode PolicyBase::AddRule(SubSystem subsystem, Semantics semantics,
   342                                const wchar_t* pattern) {
   343   if (NULL == policy_) {
   344     policy_ = MakeBrokerPolicyMemory();
   345     DCHECK(policy_);
   346     policy_maker_ = new LowLevelPolicy(policy_);
   347     DCHECK(policy_maker_);
   348   }
   350   switch (subsystem) {
   351     case SUBSYS_FILES: {
   352       if (!file_system_init_) {
   353         if (!FileSystemPolicy::SetInitialRules(policy_maker_))
   354           return SBOX_ERROR_BAD_PARAMS;
   355         file_system_init_ = true;
   356       }
   357       if (!FileSystemPolicy::GenerateRules(pattern, semantics, policy_maker_)) {
   358         NOTREACHED();
   359         return SBOX_ERROR_BAD_PARAMS;
   360       }
   361       break;
   362     }
   363     case SUBSYS_SYNC: {
   364       if (!SyncPolicy::GenerateRules(pattern, semantics, policy_maker_)) {
   365         NOTREACHED();
   366         return SBOX_ERROR_BAD_PARAMS;
   367       }
   368       break;
   369     }
   370     case SUBSYS_PROCESS: {
   371       if (lockdown_level_  < USER_INTERACTIVE &&
   372           TargetPolicy::PROCESS_ALL_EXEC == semantics) {
   373         // This is unsupported. This is a huge security risk to give full access
   374         // to a process handle.
   375         return SBOX_ERROR_UNSUPPORTED;
   376       }
   377       if (!ProcessPolicy::GenerateRules(pattern, semantics, policy_maker_)) {
   378         NOTREACHED();
   379         return SBOX_ERROR_BAD_PARAMS;
   380       }
   381       break;
   382     }
   383     case SUBSYS_NAMED_PIPES: {
   384       if (!NamedPipePolicy::GenerateRules(pattern, semantics, policy_maker_)) {
   385         NOTREACHED();
   386         return SBOX_ERROR_BAD_PARAMS;
   387       }
   388       break;
   389     }
   390     case SUBSYS_REGISTRY: {
   391       if (!RegistryPolicy::GenerateRules(pattern, semantics, policy_maker_)) {
   392         NOTREACHED();
   393         return SBOX_ERROR_BAD_PARAMS;
   394       }
   395       break;
   396     }
   397     case SUBSYS_HANDLES: {
   398       if (!HandlePolicy::GenerateRules(pattern, semantics, policy_maker_)) {
   399         NOTREACHED();
   400         return SBOX_ERROR_BAD_PARAMS;
   401       }
   402       break;
   403     }
   404     default: {
   405       return SBOX_ERROR_UNSUPPORTED;
   406     }
   407   }
   409   return SBOX_ALL_OK;
   410 }
   412 ResultCode PolicyBase::AddDllToUnload(const wchar_t* dll_name) {
   413   blacklisted_dlls_.push_back(dll_name);
   414   return SBOX_ALL_OK;
   415 }
   417 ResultCode PolicyBase::AddKernelObjectToClose(const char16* handle_type,
   418                                               const char16* handle_name) {
   419   return handle_closer_.AddHandle(handle_type, handle_name);
   420 }
   422 // When an IPC is ready in any of the targets we get called. We manage an array
   423 // of IPC dispatchers which are keyed on the IPC tag so we normally delegate
   424 // to the appropriate dispatcher unless we can handle the IPC call ourselves.
   425 Dispatcher* PolicyBase::OnMessageReady(IPCParams* ipc,
   426                                        CallbackGeneric* callback) {
   427   DCHECK(callback);
   428   static const IPCParams ping1 = {IPC_PING1_TAG, ULONG_TYPE};
   429   static const IPCParams ping2 = {IPC_PING2_TAG, INOUTPTR_TYPE};
   431   if (ping1.Matches(ipc) || ping2.Matches(ipc)) {
   432     *callback = reinterpret_cast<CallbackGeneric>(
   433                     static_cast<Callback1>(&PolicyBase::Ping));
   434     return this;
   435   }
   437   Dispatcher* dispatch = GetDispatcher(ipc->ipc_tag);
   438   if (!dispatch) {
   439     NOTREACHED();
   440     return NULL;
   441   }
   442   return dispatch->OnMessageReady(ipc, callback);
   443 }
   445 // Delegate to the appropriate dispatcher.
   446 bool PolicyBase::SetupService(InterceptionManager* manager, int service) {
   447   if (IPC_PING1_TAG == service || IPC_PING2_TAG == service)
   448     return true;
   450   Dispatcher* dispatch = GetDispatcher(service);
   451   if (!dispatch) {
   452     NOTREACHED();
   453     return false;
   454   }
   455   return dispatch->SetupService(manager, service);
   456 }
   458 ResultCode PolicyBase::MakeJobObject(HANDLE* job) {
   459   if (job_level_ != JOB_NONE) {
   460     // Create the windows job object.
   461     Job job_obj;
   462     DWORD result = job_obj.Init(job_level_, NULL, ui_exceptions_);
   463     if (ERROR_SUCCESS != result) {
   464       return SBOX_ERROR_GENERIC;
   465     }
   466     *job = job_obj.Detach();
   467   } else {
   468     *job = NULL;
   469   }
   470   return SBOX_ALL_OK;
   471 }
   473 ResultCode PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) {
   474   // Create the 'naked' token. This will be the permanent token associated
   475   // with the process and therefore with any thread that is not impersonating.
   476   DWORD result = CreateRestrictedToken(lockdown, lockdown_level_,
   477                                        integrity_level_, PRIMARY);
   478   if (ERROR_SUCCESS != result) {
   479     return SBOX_ERROR_GENERIC;
   480   }
   482   if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) {
   483     // Windows refuses to work with an impersonation token. See SetAppContainer
   484     // implementation for more details.
   485     if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_)
   486       return SBOX_ERROR_CANNOT_INIT_APPCONTAINER;
   488     *initial = INVALID_HANDLE_VALUE;
   489     return SBOX_ALL_OK;
   490   }
   492   // Create the 'better' token. We use this token as the one that the main
   493   // thread uses when booting up the process. It should contain most of
   494   // what we need (before reaching main( ))
   495   result = CreateRestrictedToken(initial, initial_level_,
   496                                  integrity_level_, IMPERSONATION);
   497   if (ERROR_SUCCESS != result) {
   498     ::CloseHandle(*lockdown);
   499     return SBOX_ERROR_GENERIC;
   500   }
   501   return SBOX_ALL_OK;
   502 }
   504 const AppContainerAttributes* PolicyBase::GetAppContainer() {
   505   if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer())
   506     return NULL;
   508   return appcontainer_list_.get();
   509 }
   511 bool PolicyBase::AddTarget(TargetProcess* target) {
   512   if (NULL != policy_)
   513     policy_maker_->Done();
   515   if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(),
   516                                                  mitigations_)) {
   517     return false;
   518   }
   520   if (!SetupAllInterceptions(target))
   521     return false;
   523   if (!SetupHandleCloser(target))
   524     return false;
   526   // Initialize the sandbox infrastructure for the target.
   527   if (ERROR_SUCCESS != target->Init(this, policy_, kIPCMemSize, kPolMemSize))
   528     return false;
   530   g_shared_delayed_integrity_level = delayed_integrity_level_;
   531   ResultCode ret = target->TransferVariable(
   532                        "g_shared_delayed_integrity_level",
   533                        &g_shared_delayed_integrity_level,
   534                        sizeof(g_shared_delayed_integrity_level));
   535   g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST;
   536   if (SBOX_ALL_OK != ret)
   537     return false;
   539   // Add in delayed mitigations and pseudo-mitigations enforced at startup.
   540   g_shared_delayed_mitigations = delayed_mitigations_ |
   541       FilterPostStartupProcessMitigations(mitigations_);
   542   if (!CanSetProcessMitigationsPostStartup(g_shared_delayed_mitigations))
   543     return false;
   545   ret = target->TransferVariable("g_shared_delayed_mitigations",
   546                                  &g_shared_delayed_mitigations,
   547                                  sizeof(g_shared_delayed_mitigations));
   548   g_shared_delayed_mitigations = 0;
   549   if (SBOX_ALL_OK != ret)
   550     return false;
   552   AutoLock lock(&lock_);
   553   targets_.push_back(target);
   554   return true;
   555 }
   557 bool PolicyBase::OnJobEmpty(HANDLE job) {
   558   AutoLock lock(&lock_);
   559   TargetSet::iterator it;
   560   for (it = targets_.begin(); it != targets_.end(); ++it) {
   561     if ((*it)->Job() == job)
   562       break;
   563   }
   564   if (it == targets_.end()) {
   565     return false;
   566   }
   567   TargetProcess* target = *it;
   568   targets_.erase(it);
   569   delete target;
   570   return true;
   571 }
   573 EvalResult PolicyBase::EvalPolicy(int service,
   574                                   CountedParameterSetBase* params) {
   575   if (NULL != policy_) {
   576     if (NULL == policy_->entry[service]) {
   577       // There is no policy for this particular service. This is not a big
   578       // deal.
   579       return DENY_ACCESS;
   580     }
   581     for (int i = 0; i < params->count; i++) {
   582       if (!params->parameters[i].IsValid()) {
   583         NOTREACHED();
   584         return SIGNAL_ALARM;
   585       }
   586     }
   587     PolicyProcessor pol_evaluator(policy_->entry[service]);
   588     PolicyResult result =  pol_evaluator.Evaluate(kShortEval,
   589                                                   params->parameters,
   590                                                   params->count);
   591     if (POLICY_MATCH == result) {
   592       return pol_evaluator.GetAction();
   593     }
   594     DCHECK(POLICY_ERROR != result);
   595   }
   597   return DENY_ACCESS;
   598 }
   600 HANDLE PolicyBase::GetStdoutHandle() {
   601   return stdout_handle_;
   602 }
   604 HANDLE PolicyBase::GetStderrHandle() {
   605   return stderr_handle_;
   606 }
   608 // We service IPC_PING_TAG message which is a way to test a round trip of the
   609 // IPC subsystem. We receive a integer cookie and we are expected to return the
   610 // cookie times two (or three) and the current tick count.
   611 bool PolicyBase::Ping(IPCInfo* ipc, void* arg1) {
   612   switch (ipc->ipc_tag) {
   613     case IPC_PING1_TAG: {
   614       IPCInt ipc_int(arg1);
   615       uint32 cookie = ipc_int.As32Bit();
   616       ipc->return_info.extended_count = 2;
   617       ipc->return_info.extended[0].unsigned_int = ::GetTickCount();
   618       ipc->return_info.extended[1].unsigned_int = 2 * cookie;
   619       return true;
   620     }
   621     case IPC_PING2_TAG: {
   622       CountedBuffer* io_buffer = reinterpret_cast<CountedBuffer*>(arg1);
   623       if (sizeof(uint32) != io_buffer->Size())
   624         return false;
   626       uint32* cookie = reinterpret_cast<uint32*>(io_buffer->Buffer());
   627       *cookie = (*cookie) * 3;
   628       return true;
   629     }
   630     default: return false;
   631   }
   632 }
   634 Dispatcher* PolicyBase::GetDispatcher(int ipc_tag) {
   635   if (ipc_tag >= IPC_LAST_TAG || ipc_tag <= IPC_UNUSED_TAG)
   636     return NULL;
   638   return ipc_targets_[ipc_tag];
   639 }
   641 bool PolicyBase::SetupAllInterceptions(TargetProcess* target) {
   642   InterceptionManager manager(target, relaxed_interceptions_);
   644   if (policy_) {
   645     for (int i = 0; i < IPC_LAST_TAG; i++) {
   646       if (policy_->entry[i] && !ipc_targets_[i]->SetupService(&manager, i))
   647           return false;
   648     }
   649   }
   651   if (!blacklisted_dlls_.empty()) {
   652     std::vector<string16>::iterator it = blacklisted_dlls_.begin();
   653     for (; it != blacklisted_dlls_.end(); ++it) {
   654       manager.AddToUnloadModules(it->c_str());
   655     }
   656   }
   658   if (!handle_closer_.SetupHandleInterceptions(&manager))
   659     return false;
   661   if (!SetupBasicInterceptions(&manager))
   662     return false;
   664   if (!manager.InitializeInterceptions())
   665     return false;
   667   // Finally, setup imports on the target so the interceptions can work.
   668   return SetupNtdllImports(target);
   669 }
   671 bool PolicyBase::SetupHandleCloser(TargetProcess* target) {
   672   return handle_closer_.InitializeTargetHandles(target);
   673 }
   675 }  // namespace sandbox

mercurial