Index: mojo/edk/system/channel_posix.cc |
diff --git a/mojo/edk/system/channel_posix.cc b/mojo/edk/system/channel_posix.cc |
index 8e6b2caa6e341e941e08c2a623f6532e5c122323..72c559bf6aadf6305efa3f11d61862fab537b067 100644 |
--- a/mojo/edk/system/channel_posix.cc |
+++ b/mojo/edk/system/channel_posix.cc |
@@ -9,6 +9,7 @@ |
#include <algorithm> |
#include <deque> |
+#include <limits> |
#include <memory> |
#include "base/bind.h" |
@@ -132,10 +133,13 @@ class ChannelPosix : public Channel, |
} |
} |
- ScopedPlatformHandleVectorPtr GetReadPlatformHandles( |
+ bool GetReadPlatformHandles( |
size_t num_handles, |
const void* extra_header, |
- size_t extra_header_size) override { |
+ size_t extra_header_size, |
+ ScopedPlatformHandleVectorPtr* handles) override { |
+ if (num_handles > std::numeric_limits<uint16_t>::max()) |
+ return false; |
#if defined(OS_MACOSX) && !defined(OS_IOS) |
// On OSX, we can have mach ports which are located in the extra header |
// section. |
@@ -147,41 +151,43 @@ class ChannelPosix : public Channel, |
reinterpret_cast<const MachPortsExtraHeader*>(extra_header); |
size_t num_mach_ports = mach_ports_header->num_ports; |
CHECK(num_mach_ports <= num_handles); |
- if (incoming_platform_handles_.size() + num_mach_ports < num_handles) |
- return nullptr; |
+ if (incoming_platform_handles_.size() + num_mach_ports < num_handles) { |
+ handles->reset(); |
+ return true; |
+ } |
- ScopedPlatformHandleVectorPtr handles( |
- new PlatformHandleVector(num_handles)); |
+ handles->reset(new PlatformHandleVector(num_handles)); |
const MachPortsEntry* mach_ports = mach_ports_header->entries; |
for (size_t i = 0, mach_port_index = 0; i < num_handles; ++i) { |
if (mach_port_index < num_mach_ports && |
mach_ports[mach_port_index].index == i) { |
- (*handles)[i] = PlatformHandle( |
+ (*handles)->at(i) = PlatformHandle( |
static_cast<mach_port_t>(mach_ports[mach_port_index].mach_port)); |
- CHECK((*handles)[i].type == PlatformHandle::Type::MACH); |
+ CHECK((*handles)->at(i).type == PlatformHandle::Type::MACH); |
// These are actually just Mach port names until they're resolved from |
// the remote process. |
- (*handles)[i].type = PlatformHandle::Type::MACH_NAME; |
+ (*handles)->at(i).type = PlatformHandle::Type::MACH_NAME; |
mach_port_index++; |
} else { |
CHECK(!incoming_platform_handles_.empty()); |
- (*handles)[i] = incoming_platform_handles_.front(); |
+ (*handles)->at(i) = incoming_platform_handles_.front(); |
incoming_platform_handles_.pop_front(); |
} |
} |
#else |
- if (incoming_platform_handles_.size() < num_handles) |
- return nullptr; |
+ if (incoming_platform_handles_.size() < num_handles) { |
+ handles->reset(); |
+ return true; |
+ } |
- ScopedPlatformHandleVectorPtr handles( |
- new PlatformHandleVector(num_handles)); |
+ handles->reset(new PlatformHandleVector(num_handles)); |
for (size_t i = 0; i < num_handles; ++i) { |
- (*handles)[i] = incoming_platform_handles_.front(); |
+ (*handles)->at(i) = incoming_platform_handles_.front(); |
incoming_platform_handles_.pop_front(); |
} |
#endif |
- return handles; |
+ return true; |
} |
private: |
@@ -395,30 +401,37 @@ class ChannelPosix : public Channel, |
} |
#if defined(OS_MACOSX) |
- void OnControlMessage(Message::Header::MessageType message_type, |
+ bool OnControlMessage(Message::Header::MessageType message_type, |
const void* payload, |
size_t payload_size, |
ScopedPlatformHandleVectorPtr handles) override { |
switch (message_type) { |
case Message::Header::MessageType::HANDLES_SENT: { |
+ if (payload_size == 0) |
+ break; |
MessagePtr message(new Channel::Message( |
payload_size, 0, Message::Header::MessageType::HANDLES_SENT_ACK)); |
memcpy(message->mutable_payload(), payload, payload_size); |
Write(std::move(message)); |
- break; |
+ return true; |
} |
+ |
case Message::Header::MessageType::HANDLES_SENT_ACK: { |
+ size_t num_fds = payload_size / sizeof(int); |
+ if (num_fds == 0 || payload_size % sizeof(int) != 0) |
+ break; |
+ |
const int* fds = reinterpret_cast<const int*>(payload); |
- size_t num_fds = payload_size / sizeof(*fds); |
- if (payload_size % sizeof(*fds) != 0 || !CloseHandles(fds, num_fds)) { |
- io_task_runner_->PostTask(FROM_HERE, |
- base::Bind(&ChannelPosix::OnError, this)); |
- } |
- break; |
+ if (!CloseHandles(fds, num_fds)) |
+ break; |
+ return true; |
} |
+ |
default: |
- NOTREACHED(); |
+ break; |
} |
+ |
+ return false; |
} |
// Closes handles referenced by |fds|. Returns false if |num_fds| is 0, or if |