socket_dispatcher.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright 2021 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. #include "sandbox/win/src/socket_dispatcher.h"
  5. #include <stdint.h>
  6. #include <winsock2.h>
  7. #include <string>
  8. #include "base/strings/string_util.h"
  9. #include "base/win/scoped_handle.h"
  10. #include "sandbox/win/src/crosscall_client.h"
  11. #include "sandbox/win/src/interception.h"
  12. #include "sandbox/win/src/interceptors.h"
  13. #include "sandbox/win/src/ipc_tags.h"
  14. #include "sandbox/win/src/policy_engine_params.h"
  15. #include "sandbox/win/src/policy_params.h"
  16. #include "sandbox/win/src/sandbox.h"
  17. namespace sandbox {
  18. namespace {
  19. class SocketHandleTraits {
  20. public:
  21. typedef SOCKET Handle;
  22. SocketHandleTraits() = delete;
  23. SocketHandleTraits(const SocketHandleTraits&) = delete;
  24. SocketHandleTraits& operator=(const SocketHandleTraits&) = delete;
  25. static bool CloseHandle(SOCKET handle) { return ::closesocket(handle) == 0; }
  26. static bool IsHandleValid(SOCKET handle) { return handle != INVALID_SOCKET; }
  27. static SOCKET NullHandle() { return INVALID_SOCKET; }
  28. };
  29. class DummySocketVerifierTraits {
  30. public:
  31. using Handle = SOCKET;
  32. DummySocketVerifierTraits() = delete;
  33. DummySocketVerifierTraits(const DummySocketVerifierTraits&) = delete;
  34. DummySocketVerifierTraits& operator=(const DummySocketVerifierTraits&) =
  35. delete;
  36. static void StartTracking(SOCKET handle,
  37. const void* owner,
  38. const void* pc1,
  39. const void* pc2) {}
  40. static void StopTracking(SOCKET handle,
  41. const void* owner,
  42. const void* pc1,
  43. const void* pc2) {}
  44. };
  45. typedef base::win::GenericScopedHandle<SocketHandleTraits,
  46. DummySocketVerifierTraits>
  47. ScopedSocketHandle;
  48. } // namespace
  49. SocketDispatcher::SocketDispatcher(PolicyBase* policy_base)
  50. : policy_base_(policy_base) {
  51. static const IPCCall create_params = {
  52. {IpcTag::WS2SOCKET,
  53. {UINT32_TYPE, UINT32_TYPE, UINT32_TYPE, INOUTPTR_TYPE}},
  54. reinterpret_cast<CallbackGeneric>(&SocketDispatcher::WS2Socket)};
  55. ipc_calls_.push_back(create_params);
  56. }
  57. bool SocketDispatcher::SetupService(InterceptionManager* manager,
  58. IpcTag service) {
  59. // This IPC has no interceptions.
  60. return true;
  61. }
  62. bool SocketDispatcher::WS2Socket(IPCInfo* ipc,
  63. uint32_t af,
  64. uint32_t type,
  65. uint32_t protocol,
  66. InOutCountedBuffer* protocol_info_buffer) {
  67. if (af != AF_INET && af != AF_INET6)
  68. return false;
  69. if (type != SOCK_STREAM && type != SOCK_DGRAM)
  70. return false;
  71. if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP)
  72. return false;
  73. if (protocol_info_buffer->Size() != sizeof(WSAPROTOCOL_INFOW))
  74. return false;
  75. CountedParameterSet<NameBased> params;
  76. // Policy for the IPC just needs to exist, the parameters here do not matter.
  77. const wchar_t* dummy_param = L"";
  78. params[NameBased::NAME] = ParamPickerMake(dummy_param);
  79. // Verify that the target process has the permission to broker sockets.
  80. if (policy_base_->EvalPolicy(IpcTag::WS2SOCKET, params.GetBase()) !=
  81. ASK_BROKER) {
  82. return false;
  83. }
  84. ScopedSocketHandle local_socket(
  85. ::WSASocketW(af, type, protocol, nullptr, 0, WSA_FLAG_OVERLAPPED));
  86. if (!local_socket.IsValid()) {
  87. ipc->return_info.extended_count = 1;
  88. ipc->return_info.extended[0].unsigned_int =
  89. static_cast<uint32_t>(::WSAGetLastError());
  90. return true;
  91. }
  92. WSAPROTOCOL_INFOW* protocol_info =
  93. reinterpret_cast<WSAPROTOCOL_INFOW*>(protocol_info_buffer->Buffer());
  94. if (::WSADuplicateSocketW(local_socket.Get(), ipc->client_info->process_id,
  95. protocol_info)) {
  96. ipc->return_info.extended_count = 1;
  97. ipc->return_info.extended[0].unsigned_int =
  98. static_cast<uint32_t>(::WSAGetLastError());
  99. return true;
  100. }
  101. return true;
  102. }
  103. } // namespace sandbox