summaryrefslogtreecommitdiffstats
path: root/ipc/mojo/ipc_channel_mojo.cc
diff options
context:
space:
mode:
authormorrita@chromium.org <morrita@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-09 06:23:01 +0000
committermorrita@chromium.org <morrita@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-09 06:24:07 +0000
commit4b32ee7a4e4996718a5cf34da3aa60b8d84bdd93 (patch)
tree94088c84d57d2e0bdd1b63b299cc262d2d8cb45d /ipc/mojo/ipc_channel_mojo.cc
parent4f3a4ae31c45fa405d9420c5a7deb9dd6a014298 (diff)
downloadchromium_src-4b32ee7a4e4996718a5cf34da3aa60b8d84bdd93.zip
chromium_src-4b32ee7a4e4996718a5cf34da3aa60b8d84bdd93.tar.gz
chromium_src-4b32ee7a4e4996718a5cf34da3aa60b8d84bdd93.tar.bz2
IPC::ChannelMojo: Dup and own fds to transmit
IPC::ChannelMojo::Send() overly closed given handles as it took the lifecycle model incorrectly. This change properly delegates the ownership of the files by using dup(). TEST=browser_tests (with ChannelMojo enabled) BUG=none R=viettrungluu@chromium.org, darin@chromium.org Review URL: https://codereview.chromium.org/452293003 Cr-Commit-Position: refs/heads/master@{#288532} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288532 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc/mojo/ipc_channel_mojo.cc')
-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;
}