summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mojo/ipc_channel_mojo.cc16
1 files changed, 14 insertions, 2 deletions
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc
index 27d35b7..d13f78b 100644
--- a/ipc/mojo/ipc_channel_mojo.cc
+++ b/ipc/mojo/ipc_channel_mojo.cc
@@ -224,18 +224,29 @@ bool ChannelMojo::MessageReader::Send(scoped_ptr<Message> message) {
message->TraceMessageBegin();
std::vector<MojoHandle> handles;
#if defined(OS_POSIX) && !defined(OS_NACL)
+ // We dup() the handles in IPC::Message to transmit.
+ // IPC::FileDescriptorSet has intricate lifecycle semantics
+ // of FDs, so just to dup()-and-own them is the safest option.
if (message->HasFileDescriptors()) {
FileDescriptorSet* fdset = message->file_descriptor_set();
for (size_t i = 0; i < fdset->size(); ++i) {
+ int fd_to_send = dup(fdset->GetDescriptorAt(i));
+ if (-1 == fd_to_send) {
+ DPLOG(WARNING) << "Failed to dup FD to transmit.";
+ std::for_each(handles.begin(), handles.end(), &MojoClose);
+ CloseWithError(MOJO_RESULT_UNKNOWN);
+ return false;
+ }
+
MojoHandle wrapped_handle;
MojoResult wrap_result = CreatePlatformHandleWrapper(
mojo::embedder::ScopedPlatformHandle(
- mojo::embedder::PlatformHandle(
- fdset->GetDescriptorAt(i))),
+ mojo::embedder::PlatformHandle(fd_to_send)),
&wrapped_handle);
if (MOJO_RESULT_OK != wrap_result) {
DLOG(WARNING) << "Pipe failed to wrap handles. Closing: "
<< wrap_result;
+ std::for_each(handles.begin(), handles.end(), &MojoClose);
CloseWithError(wrap_result);
return false;
}
@@ -251,6 +262,7 @@ bool ChannelMojo::MessageReader::Send(scoped_ptr<Message> message) {
static_cast<uint32>(handles.size()),
MOJO_WRITE_MESSAGE_FLAG_NONE);
if (MOJO_RESULT_OK != write_result) {
+ std::for_each(handles.begin(), handles.end(), &MojoClose);
CloseWithError(write_result);
return false;
}