Home | History | Annotate | Download | only in src
      1 // Copyright (c) 2006-2008 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.
      4 
      5 #include <string>
      6 
      7 #include "sandbox/win/src/sync_policy.h"
      8 
      9 #include "base/logging.h"
     10 #include "sandbox/win/src/ipc_tags.h"
     11 #include "sandbox/win/src/policy_engine_opcodes.h"
     12 #include "sandbox/win/src/policy_params.h"
     13 #include "sandbox/win/src/sandbox_types.h"
     14 #include "sandbox/win/src/sandbox_utils.h"
     15 
     16 namespace sandbox {
     17 
     18 bool SyncPolicy::GenerateRules(const wchar_t* name,
     19                                TargetPolicy::Semantics semantics,
     20                                LowLevelPolicy* policy) {
     21   std::wstring mod_name(name);
     22   if (mod_name.empty()) {
     23     return false;
     24   }
     25 
     26   if (TargetPolicy::EVENTS_ALLOW_ANY != semantics &&
     27       TargetPolicy::EVENTS_ALLOW_READONLY != semantics) {
     28     // Other flags are not valid for sync policy yet.
     29     NOTREACHED();
     30     return false;
     31   }
     32 
     33   // Add the open rule.
     34   EvalResult result = ASK_BROKER;
     35   PolicyRule open(result);
     36 
     37   if (!open.AddStringMatch(IF, OpenEventParams::NAME, name, CASE_INSENSITIVE))
     38     return false;
     39 
     40   if (TargetPolicy::EVENTS_ALLOW_READONLY == semantics) {
     41     // We consider all flags that are not known to be readonly as potentially
     42     // used for write.
     43     DWORD allowed_flags = SYNCHRONIZE | GENERIC_READ | READ_CONTROL;
     44     DWORD restricted_flags = ~allowed_flags;
     45     open.AddNumberMatch(IF_NOT, OpenEventParams::ACCESS, restricted_flags, AND);
     46   }
     47 
     48   if (!policy->AddRule(IPC_OPENEVENT_TAG, &open))
     49     return false;
     50 
     51   // If it's not a read only, add the create rule.
     52   if (TargetPolicy::EVENTS_ALLOW_READONLY != semantics) {
     53     PolicyRule create(result);
     54     if (!create.AddStringMatch(IF, NameBased::NAME, name, CASE_INSENSITIVE))
     55       return false;
     56 
     57     if (!policy->AddRule(IPC_CREATEEVENT_TAG, &create))
     58       return false;
     59   }
     60 
     61   return true;
     62 }
     63 
     64 DWORD SyncPolicy::CreateEventAction(EvalResult eval_result,
     65                                     const ClientInfo& client_info,
     66                                     const std::wstring &event_name,
     67                                     uint32 manual_reset,
     68                                     uint32 initial_state,
     69                                     HANDLE *handle) {
     70   // The only action supported is ASK_BROKER which means create the requested
     71   // file as specified.
     72   if (ASK_BROKER != eval_result)
     73     return false;
     74 
     75   HANDLE local_handle = ::CreateEvent(NULL, manual_reset, initial_state,
     76                                      event_name.c_str());
     77   if (NULL == local_handle)
     78     return ::GetLastError();
     79 
     80   if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
     81                          client_info.process, handle, 0, FALSE,
     82                          DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
     83     return ERROR_ACCESS_DENIED;
     84   }
     85   return ERROR_SUCCESS;
     86 }
     87 
     88 DWORD SyncPolicy::OpenEventAction(EvalResult eval_result,
     89                                   const ClientInfo& client_info,
     90                                   const std::wstring &event_name,
     91                                   uint32 desired_access,
     92                                   uint32 inherit_handle,
     93                                   HANDLE *handle) {
     94   // The only action supported is ASK_BROKER which means create the requested
     95   // file as specified.
     96   if (ASK_BROKER != eval_result)
     97     return false;
     98 
     99   HANDLE local_handle = ::OpenEvent(desired_access, FALSE,
    100                                     event_name.c_str());
    101   if (NULL == local_handle)
    102     return ::GetLastError();
    103 
    104   if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
    105                          client_info.process, handle, 0, inherit_handle,
    106                          DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
    107     return ERROR_ACCESS_DENIED;
    108   }
    109   return ERROR_SUCCESS;
    110 }
    111 
    112 }  // namespace sandbox
    113