michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include michael@0: michael@0: #include "sandbox/win/src/sync_policy.h" michael@0: michael@0: #include "base/logging.h" michael@0: #include "sandbox/win/src/ipc_tags.h" michael@0: #include "sandbox/win/src/policy_engine_opcodes.h" michael@0: #include "sandbox/win/src/policy_params.h" michael@0: #include "sandbox/win/src/sandbox_types.h" michael@0: #include "sandbox/win/src/sandbox_utils.h" michael@0: michael@0: namespace sandbox { michael@0: michael@0: bool SyncPolicy::GenerateRules(const wchar_t* name, michael@0: TargetPolicy::Semantics semantics, michael@0: LowLevelPolicy* policy) { michael@0: std::wstring mod_name(name); michael@0: if (mod_name.empty()) { michael@0: return false; michael@0: } michael@0: michael@0: if (TargetPolicy::EVENTS_ALLOW_ANY != semantics && michael@0: TargetPolicy::EVENTS_ALLOW_READONLY != semantics) { michael@0: // Other flags are not valid for sync policy yet. michael@0: NOTREACHED(); michael@0: return false; michael@0: } michael@0: michael@0: // Add the open rule. michael@0: EvalResult result = ASK_BROKER; michael@0: PolicyRule open(result); michael@0: michael@0: if (!open.AddStringMatch(IF, OpenEventParams::NAME, name, CASE_INSENSITIVE)) michael@0: return false; michael@0: michael@0: if (TargetPolicy::EVENTS_ALLOW_READONLY == semantics) { michael@0: // We consider all flags that are not known to be readonly as potentially michael@0: // used for write. michael@0: DWORD allowed_flags = SYNCHRONIZE | GENERIC_READ | READ_CONTROL; michael@0: DWORD restricted_flags = ~allowed_flags; michael@0: open.AddNumberMatch(IF_NOT, OpenEventParams::ACCESS, restricted_flags, AND); michael@0: } michael@0: michael@0: if (!policy->AddRule(IPC_OPENEVENT_TAG, &open)) michael@0: return false; michael@0: michael@0: // If it's not a read only, add the create rule. michael@0: if (TargetPolicy::EVENTS_ALLOW_READONLY != semantics) { michael@0: PolicyRule create(result); michael@0: if (!create.AddStringMatch(IF, NameBased::NAME, name, CASE_INSENSITIVE)) michael@0: return false; michael@0: michael@0: if (!policy->AddRule(IPC_CREATEEVENT_TAG, &create)) michael@0: return false; michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: DWORD SyncPolicy::CreateEventAction(EvalResult eval_result, michael@0: const ClientInfo& client_info, michael@0: const std::wstring &event_name, michael@0: uint32 manual_reset, michael@0: uint32 initial_state, michael@0: HANDLE *handle) { michael@0: // The only action supported is ASK_BROKER which means create the requested michael@0: // file as specified. michael@0: if (ASK_BROKER != eval_result) michael@0: return false; michael@0: michael@0: HANDLE local_handle = ::CreateEvent(NULL, manual_reset, initial_state, michael@0: event_name.c_str()); michael@0: if (NULL == local_handle) michael@0: return ::GetLastError(); michael@0: michael@0: if (!::DuplicateHandle(::GetCurrentProcess(), local_handle, michael@0: client_info.process, handle, 0, FALSE, michael@0: DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { michael@0: return ERROR_ACCESS_DENIED; michael@0: } michael@0: return ERROR_SUCCESS; michael@0: } michael@0: michael@0: DWORD SyncPolicy::OpenEventAction(EvalResult eval_result, michael@0: const ClientInfo& client_info, michael@0: const std::wstring &event_name, michael@0: uint32 desired_access, michael@0: uint32 inherit_handle, michael@0: HANDLE *handle) { michael@0: // The only action supported is ASK_BROKER which means create the requested michael@0: // file as specified. michael@0: if (ASK_BROKER != eval_result) michael@0: return false; michael@0: michael@0: HANDLE local_handle = ::OpenEvent(desired_access, FALSE, michael@0: event_name.c_str()); michael@0: if (NULL == local_handle) michael@0: return ::GetLastError(); michael@0: michael@0: if (!::DuplicateHandle(::GetCurrentProcess(), local_handle, michael@0: client_info.process, handle, 0, inherit_handle, michael@0: DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { michael@0: return ERROR_ACCESS_DENIED; michael@0: } michael@0: return ERROR_SUCCESS; michael@0: } michael@0: michael@0: } // namespace sandbox