| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013 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 "sandbox/win/src/named_pipe_dispatcher.h" | |
| 6 | |
| 7 #include <stdint.h> | |
| 8 | |
| 9 #include "base/strings/string_split.h" | |
| 10 | |
| 11 #include "sandbox/win/src/crosscall_client.h" | |
| 12 #include "sandbox/win/src/interception.h" | |
| 13 #include "sandbox/win/src/interceptors.h" | |
| 14 #include "sandbox/win/src/ipc_tags.h" | |
| 15 #include "sandbox/win/src/named_pipe_interception.h" | |
| 16 #include "sandbox/win/src/named_pipe_policy.h" | |
| 17 #include "sandbox/win/src/policy_broker.h" | |
| 18 #include "sandbox/win/src/policy_params.h" | |
| 19 #include "sandbox/win/src/sandbox.h" | |
| 20 | |
| 21 | |
| 22 namespace sandbox { | |
| 23 | |
| 24 NamedPipeDispatcher::NamedPipeDispatcher(PolicyBase* policy_base) | |
| 25 : policy_base_(policy_base) { | |
| 26 static const IPCCall create_params = { | |
| 27 {IPC_CREATENAMEDPIPEW_TAG, | |
| 28 {WCHAR_TYPE, | |
| 29 UINT32_TYPE, | |
| 30 UINT32_TYPE, | |
| 31 UINT32_TYPE, | |
| 32 UINT32_TYPE, | |
| 33 UINT32_TYPE, | |
| 34 UINT32_TYPE}}, | |
| 35 reinterpret_cast<CallbackGeneric>(&NamedPipeDispatcher::CreateNamedPipe)}; | |
| 36 | |
| 37 ipc_calls_.push_back(create_params); | |
| 38 } | |
| 39 | |
| 40 bool NamedPipeDispatcher::SetupService(InterceptionManager* manager, | |
| 41 int service) { | |
| 42 if (IPC_CREATENAMEDPIPEW_TAG == service) | |
| 43 return INTERCEPT_EAT(manager, kKerneldllName, CreateNamedPipeW, | |
| 44 CREATE_NAMED_PIPE_ID, 36); | |
| 45 | |
| 46 return false; | |
| 47 } | |
| 48 | |
| 49 bool NamedPipeDispatcher::CreateNamedPipe(IPCInfo* ipc, | |
| 50 base::string16* name, | |
| 51 uint32_t open_mode, | |
| 52 uint32_t pipe_mode, | |
| 53 uint32_t max_instances, | |
| 54 uint32_t out_buffer_size, | |
| 55 uint32_t in_buffer_size, | |
| 56 uint32_t default_timeout) { | |
| 57 ipc->return_info.win32_result = ERROR_ACCESS_DENIED; | |
| 58 ipc->return_info.handle = INVALID_HANDLE_VALUE; | |
| 59 | |
| 60 base::StringPiece16 dotdot(L".."); | |
| 61 | |
| 62 for (const base::StringPiece16& path : base::SplitStringPiece( | |
| 63 *name, base::string16(1, '/'), | |
| 64 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { | |
| 65 for (const base::StringPiece16& inner : base::SplitStringPiece( | |
| 66 path, base::string16(1, '\\'), | |
| 67 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { | |
| 68 if (inner == dotdot) | |
| 69 return true; | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 const wchar_t* pipe_name = name->c_str(); | |
| 74 CountedParameterSet<NameBased> params; | |
| 75 params[NameBased::NAME] = ParamPickerMake(pipe_name); | |
| 76 | |
| 77 EvalResult eval = policy_base_->EvalPolicy(IPC_CREATENAMEDPIPEW_TAG, | |
| 78 params.GetBase()); | |
| 79 | |
| 80 // "For file I/O, the "\\?\" prefix to a path string tells the Windows APIs to | |
| 81 // disable all string parsing and to send the string that follows it straight | |
| 82 // to the file system." | |
| 83 // http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx | |
| 84 // This ensures even if there is a path traversal in the pipe name, and it is | |
| 85 // able to get past the checks above, it will still not be allowed to escape | |
| 86 // our whitelisted namespace. | |
| 87 if (name->compare(0, 4, L"\\\\.\\") == 0) | |
| 88 name->replace(0, 4, L"\\\\\?\\"); | |
| 89 | |
| 90 HANDLE pipe; | |
| 91 DWORD ret = NamedPipePolicy::CreateNamedPipeAction(eval, *ipc->client_info, | |
| 92 *name, open_mode, | |
| 93 pipe_mode, max_instances, | |
| 94 out_buffer_size, | |
| 95 in_buffer_size, | |
| 96 default_timeout, &pipe); | |
| 97 | |
| 98 ipc->return_info.win32_result = ret; | |
| 99 ipc->return_info.handle = pipe; | |
| 100 return true; | |
| 101 } | |
| 102 | |
| 103 } // namespace sandbox | |
| OLD | NEW |