| OLD | NEW | 
|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 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 <string> | 5 #include <string> | 
| 6 | 6 | 
| 7 #include "sandbox/win/src/sync_policy.h" | 7 #include "sandbox/win/src/sync_policy.h" | 
| 8 | 8 | 
| 9 #include "base/logging.h" | 9 #include "base/logging.h" | 
|  | 10 #include "base/strings/stringprintf.h" | 
| 10 #include "sandbox/win/src/ipc_tags.h" | 11 #include "sandbox/win/src/ipc_tags.h" | 
|  | 12 #include "sandbox/win/src/nt_internals.h" | 
| 11 #include "sandbox/win/src/policy_engine_opcodes.h" | 13 #include "sandbox/win/src/policy_engine_opcodes.h" | 
| 12 #include "sandbox/win/src/policy_params.h" | 14 #include "sandbox/win/src/policy_params.h" | 
| 13 #include "sandbox/win/src/sandbox_types.h" | 15 #include "sandbox/win/src/sandbox_types.h" | 
| 14 #include "sandbox/win/src/sandbox_utils.h" | 16 #include "sandbox/win/src/sandbox_utils.h" | 
|  | 17 #include "sandbox/win/src/sync_interception.h" | 
|  | 18 #include "sandbox/win/src/win_utils.h" | 
| 15 | 19 | 
| 16 namespace sandbox { | 20 namespace sandbox { | 
| 17 | 21 | 
|  | 22 // Provides functionality to resolve a symbolic link within the object | 
|  | 23 // directory passed in. | 
|  | 24 NTSTATUS ResolveSymbolicLink(const std::wstring& directory_name, | 
|  | 25                              const std::wstring& name, | 
|  | 26                              std::wstring* target) { | 
|  | 27   NtOpenDirectoryObjectFunction NtOpenDirectoryObject = NULL; | 
|  | 28   ResolveNTFunctionPtr("NtOpenDirectoryObject", &NtOpenDirectoryObject); | 
|  | 29 | 
|  | 30   NtQuerySymbolicLinkObjectFunction NtQuerySymbolicLinkObject = NULL; | 
|  | 31   ResolveNTFunctionPtr("NtQuerySymbolicLinkObject", | 
|  | 32                        &NtQuerySymbolicLinkObject); | 
|  | 33 | 
|  | 34   NtOpenSymbolicLinkObjectFunction NtOpenSymbolicLinkObject = NULL; | 
|  | 35   ResolveNTFunctionPtr("NtOpenSymbolicLinkObject", &NtOpenSymbolicLinkObject); | 
|  | 36 | 
|  | 37   NtCloseFunction NtClose = NULL; | 
|  | 38   ResolveNTFunctionPtr("NtClose", &NtClose); | 
|  | 39 | 
|  | 40   OBJECT_ATTRIBUTES symbolic_link_directory_attributes = {}; | 
|  | 41   UNICODE_STRING symbolic_link_directory_string = {}; | 
|  | 42   InitObjectAttribs(directory_name, OBJ_CASE_INSENSITIVE, NULL, | 
|  | 43                     &symbolic_link_directory_attributes, | 
|  | 44                     &symbolic_link_directory_string); | 
|  | 45 | 
|  | 46   HANDLE symbolic_link_directory = NULL; | 
|  | 47   NTSTATUS status = NtOpenDirectoryObject(&symbolic_link_directory, | 
|  | 48                                           DIRECTORY_QUERY, | 
|  | 49                                           &symbolic_link_directory_attributes); | 
|  | 50   if (status != STATUS_SUCCESS) { | 
|  | 51     DLOG(ERROR) << "Failed to open symbolic link directory. Error: " | 
|  | 52                 << status; | 
|  | 53     return status; | 
|  | 54   } | 
|  | 55 | 
|  | 56   OBJECT_ATTRIBUTES symbolic_link_attributes = {}; | 
|  | 57   UNICODE_STRING name_string = {}; | 
|  | 58   InitObjectAttribs(name, OBJ_CASE_INSENSITIVE, symbolic_link_directory, | 
|  | 59                     &symbolic_link_attributes, &name_string); | 
|  | 60 | 
|  | 61   HANDLE symbolic_link = NULL; | 
|  | 62   status = NtOpenSymbolicLinkObject(&symbolic_link, GENERIC_READ, | 
|  | 63                                     &symbolic_link_attributes); | 
|  | 64   NtClose(symbolic_link_directory); | 
|  | 65   if (status != STATUS_SUCCESS) { | 
|  | 66     DLOG(ERROR) << "Failed to open symbolic link Error: " << status; | 
|  | 67     return status; | 
|  | 68   } | 
|  | 69 | 
|  | 70   UNICODE_STRING target_path = {}; | 
|  | 71   unsigned long target_length = 0; | 
|  | 72   status = NtQuerySymbolicLinkObject(symbolic_link, &target_path, | 
|  | 73                                      &target_length); | 
|  | 74   if (status != STATUS_BUFFER_TOO_SMALL) { | 
|  | 75     NtClose(symbolic_link); | 
|  | 76     DLOG(ERROR) << "Failed to get length for symbolic link target. Error: " | 
|  | 77                 << status; | 
|  | 78     return status; | 
|  | 79   } | 
|  | 80 | 
|  | 81   target_path.Buffer = new wchar_t[target_length + 1]; | 
|  | 82   target_path.Length = 0; | 
|  | 83   target_path.MaximumLength = target_length; | 
|  | 84   status = NtQuerySymbolicLinkObject(symbolic_link, &target_path, | 
|  | 85                                      &target_length); | 
|  | 86   if (status == STATUS_SUCCESS) { | 
|  | 87     target->assign(target_path.Buffer, target_length); | 
|  | 88   } else { | 
|  | 89     DLOG(ERROR) << "Failed to resolve symbolic link. Error: " << status; | 
|  | 90   } | 
|  | 91 | 
|  | 92   NtClose(symbolic_link); | 
|  | 93   delete[] target_path.Buffer; | 
|  | 94   return status; | 
|  | 95 } | 
|  | 96 | 
|  | 97 NTSTATUS GetBaseNamedObjectsDirectory(HANDLE* directory) { | 
|  | 98   static HANDLE base_named_objects_handle = NULL; | 
|  | 99   if (base_named_objects_handle) { | 
|  | 100     *directory = base_named_objects_handle; | 
|  | 101     return STATUS_SUCCESS; | 
|  | 102   } | 
|  | 103 | 
|  | 104   NtOpenDirectoryObjectFunction NtOpenDirectoryObject = NULL; | 
|  | 105   ResolveNTFunctionPtr("NtOpenDirectoryObject", &NtOpenDirectoryObject); | 
|  | 106 | 
|  | 107   DWORD session_id = 0; | 
|  | 108   ProcessIdToSessionId(::GetCurrentProcessId(), &session_id); | 
|  | 109 | 
|  | 110   std::wstring base_named_objects_path; | 
|  | 111 | 
|  | 112   NTSTATUS status = ResolveSymbolicLink(L"\\Sessions\\BNOLINKS", | 
|  | 113                                         base::StringPrintf(L"%d", session_id), | 
|  | 114                                         &base_named_objects_path); | 
|  | 115   if (status != STATUS_SUCCESS) { | 
|  | 116     DLOG(ERROR) << "Failed to resolve BaseNamedObjects path. Error: " | 
|  | 117                 << status; | 
|  | 118     return status; | 
|  | 119   } | 
|  | 120 | 
|  | 121   UNICODE_STRING directory_name = {}; | 
|  | 122   OBJECT_ATTRIBUTES object_attributes = {}; | 
|  | 123   InitObjectAttribs(base_named_objects_path, OBJ_CASE_INSENSITIVE, NULL, | 
|  | 124                     &object_attributes, &directory_name); | 
|  | 125   status = NtOpenDirectoryObject(&base_named_objects_handle, | 
|  | 126                                  DIRECTORY_ALL_ACCESS, | 
|  | 127                                  &object_attributes); | 
|  | 128   if (status == STATUS_SUCCESS) | 
|  | 129     *directory = base_named_objects_handle; | 
|  | 130   return status; | 
|  | 131 } | 
|  | 132 | 
| 18 bool SyncPolicy::GenerateRules(const wchar_t* name, | 133 bool SyncPolicy::GenerateRules(const wchar_t* name, | 
| 19                                TargetPolicy::Semantics semantics, | 134                                TargetPolicy::Semantics semantics, | 
| 20                                LowLevelPolicy* policy) { | 135                                LowLevelPolicy* policy) { | 
| 21   std::wstring mod_name(name); | 136   std::wstring mod_name(name); | 
| 22   if (mod_name.empty()) { | 137   if (mod_name.empty()) { | 
| 23     return false; | 138     return false; | 
| 24   } | 139   } | 
| 25 | 140 | 
| 26   if (TargetPolicy::EVENTS_ALLOW_ANY != semantics && | 141   if (TargetPolicy::EVENTS_ALLOW_ANY != semantics && | 
| 27       TargetPolicy::EVENTS_ALLOW_READONLY != semantics) { | 142       TargetPolicy::EVENTS_ALLOW_READONLY != semantics) { | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 57     if (!policy->AddRule(IPC_CREATEEVENT_TAG, &create)) | 172     if (!policy->AddRule(IPC_CREATEEVENT_TAG, &create)) | 
| 58       return false; | 173       return false; | 
| 59   } | 174   } | 
| 60 | 175 | 
| 61   return true; | 176   return true; | 
| 62 } | 177 } | 
| 63 | 178 | 
| 64 DWORD SyncPolicy::CreateEventAction(EvalResult eval_result, | 179 DWORD SyncPolicy::CreateEventAction(EvalResult eval_result, | 
| 65                                     const ClientInfo& client_info, | 180                                     const ClientInfo& client_info, | 
| 66                                     const std::wstring &event_name, | 181                                     const std::wstring &event_name, | 
| 67                                     uint32 manual_reset, | 182                                     uint32 event_type, | 
| 68                                     uint32 initial_state, | 183                                     uint32 initial_state, | 
| 69                                     HANDLE *handle) { | 184                                     HANDLE *handle) { | 
|  | 185   NtCreateEventFunction NtCreateEvent = NULL; | 
|  | 186   ResolveNTFunctionPtr("NtCreateEvent", &NtCreateEvent); | 
|  | 187 | 
| 70   // The only action supported is ASK_BROKER which means create the requested | 188   // The only action supported is ASK_BROKER which means create the requested | 
| 71   // file as specified. | 189   // file as specified. | 
| 72   if (ASK_BROKER != eval_result) | 190   if (ASK_BROKER != eval_result) | 
| 73     return false; | 191     return false; | 
| 74 | 192 | 
| 75   HANDLE local_handle = ::CreateEvent(NULL, manual_reset, initial_state, | 193   HANDLE object_directory = NULL; | 
| 76                                      event_name.c_str()); | 194   NTSTATUS status = GetBaseNamedObjectsDirectory(&object_directory); | 
|  | 195   if (status != STATUS_SUCCESS) | 
|  | 196     return status; | 
|  | 197 | 
|  | 198   UNICODE_STRING unicode_event_name = {}; | 
|  | 199   OBJECT_ATTRIBUTES object_attributes = {}; | 
|  | 200   InitObjectAttribs(event_name, OBJ_CASE_INSENSITIVE, object_directory, | 
|  | 201                     &object_attributes, &unicode_event_name); | 
|  | 202 | 
|  | 203   HANDLE local_handle = NULL; | 
|  | 204   status = NtCreateEvent(&local_handle, EVENT_ALL_ACCESS, &object_attributes, | 
|  | 205                          static_cast<EVENT_TYPE>(event_type), initial_state); | 
| 77   if (NULL == local_handle) | 206   if (NULL == local_handle) | 
| 78     return ::GetLastError(); | 207     return status; | 
| 79 | 208 | 
| 80   if (!::DuplicateHandle(::GetCurrentProcess(), local_handle, | 209   if (!::DuplicateHandle(::GetCurrentProcess(), local_handle, | 
| 81                          client_info.process, handle, 0, FALSE, | 210                          client_info.process, handle, 0, FALSE, | 
| 82                          DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 211                          DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 
| 83     return ERROR_ACCESS_DENIED; | 212     return STATUS_ACCESS_DENIED; | 
| 84   } | 213   } | 
| 85   return ERROR_SUCCESS; | 214   return status; | 
| 86 } | 215 } | 
| 87 | 216 | 
| 88 DWORD SyncPolicy::OpenEventAction(EvalResult eval_result, | 217 DWORD SyncPolicy::OpenEventAction(EvalResult eval_result, | 
| 89                                   const ClientInfo& client_info, | 218                                   const ClientInfo& client_info, | 
| 90                                   const std::wstring &event_name, | 219                                   const std::wstring &event_name, | 
| 91                                   uint32 desired_access, | 220                                   uint32 desired_access, | 
| 92                                   uint32 inherit_handle, |  | 
| 93                                   HANDLE *handle) { | 221                                   HANDLE *handle) { | 
|  | 222   NtOpenEventFunction NtOpenEvent = NULL; | 
|  | 223   ResolveNTFunctionPtr("NtOpenEvent", &NtOpenEvent); | 
|  | 224 | 
| 94   // The only action supported is ASK_BROKER which means create the requested | 225   // The only action supported is ASK_BROKER which means create the requested | 
| 95   // file as specified. | 226   // event as specified. | 
| 96   if (ASK_BROKER != eval_result) | 227   if (ASK_BROKER != eval_result) | 
| 97     return false; | 228     return false; | 
| 98 | 229 | 
| 99   HANDLE local_handle = ::OpenEvent(desired_access, FALSE, | 230   HANDLE object_directory = NULL; | 
| 100                                     event_name.c_str()); | 231   NTSTATUS status = GetBaseNamedObjectsDirectory(&object_directory); | 
|  | 232   if (status != STATUS_SUCCESS) | 
|  | 233     return status; | 
|  | 234 | 
|  | 235   UNICODE_STRING unicode_event_name = {}; | 
|  | 236   OBJECT_ATTRIBUTES object_attributes = {}; | 
|  | 237   InitObjectAttribs(event_name, OBJ_CASE_INSENSITIVE, object_directory, | 
|  | 238                     &object_attributes, &unicode_event_name); | 
|  | 239 | 
|  | 240   HANDLE local_handle = NULL; | 
|  | 241   status = NtOpenEvent(&local_handle, desired_access, &object_attributes); | 
| 101   if (NULL == local_handle) | 242   if (NULL == local_handle) | 
| 102     return ::GetLastError(); | 243     return status; | 
| 103 | 244 | 
| 104   if (!::DuplicateHandle(::GetCurrentProcess(), local_handle, | 245   if (!::DuplicateHandle(::GetCurrentProcess(), local_handle, | 
| 105                          client_info.process, handle, 0, inherit_handle, | 246                          client_info.process, handle, 0, FALSE, | 
| 106                          DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 247                          DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 
| 107     return ERROR_ACCESS_DENIED; | 248     return STATUS_ACCESS_DENIED; | 
| 108   } | 249   } | 
| 109   return ERROR_SUCCESS; | 250   return status; | 
| 110 } | 251 } | 
| 111 | 252 | 
| 112 }  // namespace sandbox | 253 }  // namespace sandbox | 
| OLD | NEW | 
|---|