OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "mojo/edk/system/broker_host.h" | 5 #include "mojo/edk/system/broker_host.h" |
6 | 6 |
7 #include <fcntl.h> | |
8 #include <unistd.h> | |
9 | |
10 #include <utility> | 7 #include <utility> |
11 | 8 |
12 #include "base/logging.h" | 9 #include "base/logging.h" |
13 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
14 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
15 #include "base/threading/thread_task_runner_handle.h" | 12 #include "base/threading/thread_task_runner_handle.h" |
16 #include "mojo/edk/embedder/embedder_internal.h" | |
17 #include "mojo/edk/embedder/platform_channel_utils_posix.h" | |
18 #include "mojo/edk/embedder/platform_handle_vector.h" | 13 #include "mojo/edk/embedder/platform_handle_vector.h" |
19 #include "mojo/edk/embedder/platform_shared_buffer.h" | 14 #include "mojo/edk/embedder/platform_shared_buffer.h" |
20 #include "mojo/edk/system/broker_messages.h" | 15 #include "mojo/edk/system/broker_messages.h" |
21 | 16 |
22 namespace mojo { | 17 namespace mojo { |
23 namespace edk { | 18 namespace edk { |
24 | 19 |
25 namespace { | 20 namespace { |
| 21 |
26 // To prevent abuse, limit the maximum size of shared memory buffers. | 22 // To prevent abuse, limit the maximum size of shared memory buffers. |
27 // TODO(amistry): Re-consider this limit, or do something smarter. | 23 // TODO(rockot): Re-consider this limit, or do something smarter. |
28 const size_t kMaxSharedBufferSize = 16 * 1024 * 1024; | 24 const uint32_t kMaxSharedBufferSize = 16 * 1024 * 1024; |
29 } | |
30 | 25 |
31 BrokerHost::BrokerHost(ScopedPlatformHandle platform_handle) { | 26 } // namespace |
| 27 |
| 28 BrokerHost::BrokerHost(base::ProcessHandle client_process, |
| 29 ScopedPlatformHandle platform_handle) |
| 30 #if defined(OS_WIN) |
| 31 : client_process_(client_process) |
| 32 #endif |
| 33 { |
32 CHECK(platform_handle.is_valid()); | 34 CHECK(platform_handle.is_valid()); |
33 | 35 |
34 base::MessageLoop::current()->AddDestructionObserver(this); | 36 base::MessageLoop::current()->AddDestructionObserver(this); |
35 | 37 |
36 channel_ = Channel::Create(this, std::move(platform_handle), | 38 channel_ = Channel::Create( |
37 base::ThreadTaskRunnerHandle::Get()); | 39 this, std::move(platform_handle), base::ThreadTaskRunnerHandle::Get()); |
38 channel_->Start(); | 40 channel_->Start(); |
39 } | 41 } |
40 | 42 |
41 BrokerHost::~BrokerHost() { | 43 BrokerHost::~BrokerHost() { |
42 // We're always destroyed on the creation thread, which is the IO thread. | 44 // We're always destroyed on the creation thread, which is the IO thread. |
43 base::MessageLoop::current()->RemoveDestructionObserver(this); | 45 base::MessageLoop::current()->RemoveDestructionObserver(this); |
44 | 46 |
45 if (channel_) | 47 if (channel_) |
46 channel_->ShutDown(); | 48 channel_->ShutDown(); |
47 } | 49 } |
48 | 50 |
| 51 void BrokerHost::PrepareHandlesForClient(PlatformHandleVector* handles) { |
| 52 #if defined(OS_WIN) |
| 53 if (!Channel::Message::RewriteHandles( |
| 54 base::GetCurrentProcessHandle(), client_process_, handles)) { |
| 55 // NOTE: We only log an error here. We do not signal a logical error or |
| 56 // prevent any message from being sent. The client should handle unexpected |
| 57 // invalid handles appropriately. |
| 58 DLOG(ERROR) << "Failed to rewrite one or more handles to broker client."; |
| 59 } |
| 60 #endif |
| 61 } |
| 62 |
49 void BrokerHost::SendChannel(ScopedPlatformHandle handle) { | 63 void BrokerHost::SendChannel(ScopedPlatformHandle handle) { |
50 CHECK(handle.is_valid()); | 64 CHECK(handle.is_valid()); |
51 CHECK(channel_); | 65 CHECK(channel_); |
52 | 66 |
53 Channel::MessagePtr message = | 67 Channel::MessagePtr message = |
54 CreateBrokerMessage(BrokerMessageType::INIT, 1, nullptr); | 68 CreateBrokerMessage(BrokerMessageType::INIT, 1, nullptr); |
55 ScopedPlatformHandleVectorPtr handles; | 69 ScopedPlatformHandleVectorPtr handles; |
56 handles.reset(new PlatformHandleVector(1)); | 70 handles.reset(new PlatformHandleVector(1)); |
57 handles->at(0) = handle.release(); | 71 handles->at(0) = handle.release(); |
| 72 PrepareHandlesForClient(handles.get()); |
58 message->SetHandles(std::move(handles)); | 73 message->SetHandles(std::move(handles)); |
59 | |
60 channel_->Write(std::move(message)); | 74 channel_->Write(std::move(message)); |
61 } | 75 } |
62 | 76 |
63 void BrokerHost::OnBufferRequest(size_t num_bytes) { | 77 void BrokerHost::OnBufferRequest(uint32_t num_bytes) { |
64 scoped_refptr<PlatformSharedBuffer> buffer; | 78 scoped_refptr<PlatformSharedBuffer> buffer; |
65 scoped_refptr<PlatformSharedBuffer> read_only_buffer; | 79 scoped_refptr<PlatformSharedBuffer> read_only_buffer; |
66 if (num_bytes <= kMaxSharedBufferSize) { | 80 if (num_bytes <= kMaxSharedBufferSize) { |
67 buffer = PlatformSharedBuffer::Create(num_bytes); | 81 buffer = PlatformSharedBuffer::Create(num_bytes); |
68 if (buffer) | 82 if (buffer) |
69 read_only_buffer = buffer->CreateReadOnlyDuplicate(); | 83 read_only_buffer = buffer->CreateReadOnlyDuplicate(); |
70 if (!read_only_buffer) | 84 if (!read_only_buffer) |
71 buffer = nullptr; | 85 buffer = nullptr; |
72 } else { | 86 } else { |
73 LOG(ERROR) << "Shared buffer request too large: " << num_bytes; | 87 LOG(ERROR) << "Shared buffer request too large: " << num_bytes; |
74 } | 88 } |
75 | 89 |
76 Channel::MessagePtr message = CreateBrokerMessage( | 90 Channel::MessagePtr message = CreateBrokerMessage( |
77 BrokerMessageType::BUFFER_RESPONSE, buffer ? 2 : 0, nullptr); | 91 BrokerMessageType::BUFFER_RESPONSE, buffer ? 2 : 0, nullptr); |
78 if (buffer) { | 92 if (buffer) { |
79 ScopedPlatformHandleVectorPtr handles; | 93 ScopedPlatformHandleVectorPtr handles; |
80 handles.reset(new PlatformHandleVector(2)); | 94 handles.reset(new PlatformHandleVector(2)); |
81 handles->at(0) = buffer->PassPlatformHandle().release(); | 95 handles->at(0) = buffer->PassPlatformHandle().release(); |
82 handles->at(1) = read_only_buffer->PassPlatformHandle().release(); | 96 handles->at(1) = read_only_buffer->PassPlatformHandle().release(); |
| 97 PrepareHandlesForClient(handles.get()); |
83 message->SetHandles(std::move(handles)); | 98 message->SetHandles(std::move(handles)); |
84 } | 99 } |
85 | 100 |
86 channel_->Write(std::move(message)); | 101 channel_->Write(std::move(message)); |
87 } | 102 } |
88 | 103 |
89 void BrokerHost::OnChannelMessage(const void* payload, | 104 void BrokerHost::OnChannelMessage(const void* payload, |
90 size_t payload_size, | 105 size_t payload_size, |
91 ScopedPlatformHandleVectorPtr handles) { | 106 ScopedPlatformHandleVectorPtr handles) { |
92 if (payload_size < sizeof(BrokerMessageHeader)) | 107 if (payload_size < sizeof(BrokerMessageHeader)) |
93 return; | 108 return; |
94 | 109 |
95 const BrokerMessageHeader* header = | 110 const BrokerMessageHeader* header = |
96 static_cast<const BrokerMessageHeader*>(payload); | 111 static_cast<const BrokerMessageHeader*>(payload); |
97 switch (header->type) { | 112 switch (header->type) { |
98 case BrokerMessageType::BUFFER_REQUEST: | 113 case BrokerMessageType::BUFFER_REQUEST: |
99 if (payload_size == | 114 if (payload_size == |
100 sizeof(BrokerMessageHeader) + sizeof(BufferRequestData)) { | 115 sizeof(BrokerMessageHeader) + sizeof(BufferRequestData)) { |
101 const BufferRequestData* request = | 116 const BufferRequestData* request = |
102 reinterpret_cast<const BufferRequestData*>(header + 1); | 117 reinterpret_cast<const BufferRequestData*>(header + 1); |
103 OnBufferRequest(request->size); | 118 OnBufferRequest(request->size); |
104 return; | |
105 } | 119 } |
106 break; | 120 break; |
107 | 121 |
108 default: | 122 default: |
| 123 LOG(ERROR) << "Unexpected broker message type: " << header->type; |
109 break; | 124 break; |
110 } | 125 } |
111 | |
112 LOG(ERROR) << "Unexpected broker message type: " << header->type; | |
113 } | 126 } |
114 | 127 |
115 void BrokerHost::OnChannelError() { | 128 void BrokerHost::OnChannelError() { delete this; } |
116 if (channel_) { | |
117 channel_->ShutDown(); | |
118 channel_ = nullptr; | |
119 } | |
120 | 129 |
121 delete this; | 130 void BrokerHost::WillDestroyCurrentMessageLoop() { delete this; } |
122 } | |
123 | |
124 void BrokerHost::WillDestroyCurrentMessageLoop() { | |
125 delete this; | |
126 } | |
127 | 131 |
128 } // namespace edk | 132 } // namespace edk |
129 } // namespace mojo | 133 } // namespace mojo |
OLD | NEW |