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