summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorerikchen <erikchen@chromium.org>2015-08-11 14:17:47 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-11 21:18:44 +0000
commit959039d06c1677f2d90fc7d84cb9ad9d310842bd (patch)
treebf326c766e7d0b040bcbcf0110f73d3b7d0ddd5a /ipc
parent1d30631db4ff58e63c4ae4b7132cb136fb0c37b3 (diff)
downloadchromium_src-959039d06c1677f2d90fc7d84cb9ad9d310842bd.zip
chromium_src-959039d06c1677f2d90fc7d84cb9ad9d310842bd.tar.gz
chromium_src-959039d06c1677f2d90fc7d84cb9ad9d310842bd.tar.bz2
ipc: Add the class HandleWin.
HandleWin is a wrapper around a Windows HANDLE that can be transported across IPC channels that support attachment brokering. The attachment broker is responsible for duplicating the HANDLE into the destination process. BUG=493414 Review URL: https://codereview.chromium.org/1281083004 Cr-Commit-Position: refs/heads/master@{#342897}
Diffstat (limited to 'ipc')
-rw-r--r--ipc/BUILD.gn2
-rw-r--r--ipc/attachment_broker_messages.h4
-rw-r--r--ipc/attachment_broker_privileged_win.cc23
-rw-r--r--ipc/attachment_broker_privileged_win.h2
-rw-r--r--ipc/attachment_broker_privileged_win_unittest.cc31
-rw-r--r--ipc/attachment_broker_unprivileged_win_unittest.cc4
-rw-r--r--ipc/handle_attachment_win.cc14
-rw-r--r--ipc/handle_attachment_win.h6
-rw-r--r--ipc/handle_win.cc53
-rw-r--r--ipc/handle_win.h52
-rw-r--r--ipc/ipc.gypi2
11 files changed, 179 insertions, 14 deletions
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn
index eb59274..2fe70bb 100644
--- a/ipc/BUILD.gn
+++ b/ipc/BUILD.gn
@@ -21,6 +21,8 @@ component("ipc") {
"brokerable_attachment.h",
"handle_attachment_win.cc",
"handle_attachment_win.h",
+ "handle_win.cc",
+ "handle_win.h",
"ipc_channel.cc",
"ipc_channel.h",
"ipc_channel_common.cc",
diff --git a/ipc/attachment_broker_messages.h b/ipc/attachment_broker_messages.h
index 066e19c..f0e103d 100644
--- a/ipc/attachment_broker_messages.h
+++ b/ipc/attachment_broker_messages.h
@@ -19,9 +19,13 @@
// ----------------------------------------------------------------------------
#if defined(OS_WIN)
+// Define the serialization for Permissions.
+IPC_ENUM_TRAITS_MAX_VALUE(HandleWin::Permissions, HandleWin::MAX_PERMISSIONS);
+
IPC_STRUCT_TRAITS_BEGIN(IPC::internal::HandleAttachmentWin::WireFormat)
IPC_STRUCT_TRAITS_MEMBER(handle)
IPC_STRUCT_TRAITS_MEMBER(destination_process)
+ IPC_STRUCT_TRAITS_MEMBER(permissions)
IPC_STRUCT_TRAITS_MEMBER(attachment_id)
IPC_STRUCT_TRAITS_END()
#endif // defined(OS_WIN)
diff --git a/ipc/attachment_broker_privileged_win.cc b/ipc/attachment_broker_privileged_win.cc
index 77584cf..c8cc1d0 100644
--- a/ipc/attachment_broker_privileged_win.cc
+++ b/ipc/attachment_broker_privileged_win.cc
@@ -95,6 +95,8 @@ AttachmentBrokerPrivilegedWin::DuplicateWinHandle(
HandleWireFormat new_wire_format;
new_wire_format.destination_process = wire_format.destination_process;
new_wire_format.attachment_id = wire_format.attachment_id;
+ new_wire_format.permissions = wire_format.permissions;
+ new_wire_format.handle = 0;
HANDLE original_handle = LongToHandle(wire_format.handle);
@@ -103,15 +105,28 @@ AttachmentBrokerPrivilegedWin::DuplicateWinHandle(
base::Process dest_process =
base::Process::OpenWithExtraPrivileges(wire_format.destination_process);
if (source_process.Handle() && dest_process.Handle()) {
+ DWORD desired_access = 0;
+ DWORD options = 0;
+ switch (wire_format.permissions) {
+ case HandleWin::INVALID:
+ LOG(ERROR) << "Received invalid permissions for duplication.";
+ return new_wire_format;
+ case HandleWin::DUPLICATE:
+ options = DUPLICATE_SAME_ACCESS;
+ break;
+ case HandleWin::FILE_READ_WRITE:
+ desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
+ break;
+ }
+
HANDLE new_handle;
DWORD result = ::DuplicateHandle(source_process.Handle(), original_handle,
- dest_process.Handle(), &new_handle, 0,
- FALSE, DUPLICATE_SAME_ACCESS);
+ dest_process.Handle(), &new_handle,
+ desired_access, FALSE, options);
new_wire_format.handle = (result != 0) ? HandleToLong(new_handle) : 0;
- } else {
- new_wire_format.handle = 0;
}
+
return new_wire_format;
}
diff --git a/ipc/attachment_broker_privileged_win.h b/ipc/attachment_broker_privileged_win.h
index dca05f5..67104b8 100644
--- a/ipc/attachment_broker_privileged_win.h
+++ b/ipc/attachment_broker_privileged_win.h
@@ -29,7 +29,7 @@ class IPC_EXPORT AttachmentBrokerPrivilegedWin
private:
using HandleWireFormat = internal::HandleAttachmentWin::WireFormat;
// IPC message handlers.
- void OnDuplicateWinHandle(const IPC::Message& message);
+ void OnDuplicateWinHandle(const Message& message);
// Duplicates |wire_Format| from |source_process| into its destination
// process.
diff --git a/ipc/attachment_broker_privileged_win_unittest.cc b/ipc/attachment_broker_privileged_win_unittest.cc
index 3df4006..6e8f881 100644
--- a/ipc/attachment_broker_privileged_win_unittest.cc
+++ b/ipc/attachment_broker_privileged_win_unittest.cc
@@ -13,6 +13,7 @@
#include "ipc/attachment_broker_privileged_win.h"
#include "ipc/attachment_broker_unprivileged_win.h"
#include "ipc/handle_attachment_win.h"
+#include "ipc/handle_win.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_test_base.h"
@@ -191,7 +192,7 @@ class IPCAttachmentBrokerPrivilegedWinTest : public IPCTestBase {
new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
message->WriteInt(message_index_++);
scoped_refptr<IPC::internal::HandleAttachmentWin> attachment(
- new IPC::internal::HandleAttachmentWin(h));
+ new IPC::internal::HandleAttachmentWin(h, IPC::HandleWin::DUPLICATE));
ASSERT_TRUE(message->WriteAttachment(attachment));
sender()->Send(message);
}
@@ -305,6 +306,30 @@ TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleToSelf) {
CommonTearDown();
}
+// Similar to SendHandle, except this test uses the HandleWin class.
+TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleWin) {
+ Init("SendHandleWin");
+
+ CommonSetUp();
+ ResultListener result_listener;
+ get_proxy_listener()->set_listener(&result_listener);
+
+ HANDLE h = CreateTempFile();
+ IPC::HandleWin handle_win(h, IPC::HandleWin::FILE_READ_WRITE);
+ IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
+ message->WriteInt(0);
+ IPC::ParamTraits<IPC::HandleWin>::Write(message, handle_win);
+ sender()->Send(message);
+ base::MessageLoop::current()->Run();
+
+ // Check the result.
+ ASSERT_EQ(ProxyListener::MESSAGE_RECEIVED,
+ get_proxy_listener()->get_reason());
+ ASSERT_EQ(result_listener.get_result(), RESULT_SUCCESS);
+
+ CommonTearDown();
+}
+
using OnMessageReceivedCallback =
void (*)(MockObserver* observer,
IPC::AttachmentBrokerPrivilegedWin* broker,
@@ -399,4 +424,8 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleToSelf) {
"SendHandleToSelf");
}
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendHandleWin) {
+ return CommonPrivilegedProcessMain(&SendHandleCallback, "SendHandleWin");
+}
+
} // namespace
diff --git a/ipc/attachment_broker_unprivileged_win_unittest.cc b/ipc/attachment_broker_unprivileged_win_unittest.cc
index c260997..e67c54a 100644
--- a/ipc/attachment_broker_unprivileged_win_unittest.cc
+++ b/ipc/attachment_broker_unprivileged_win_unittest.cc
@@ -20,7 +20,7 @@ TEST(AttachmentBrokerUnprivilegedWinTest, ReceiveValidMessage) {
HANDLE handle = LongToHandle(8);
base::ProcessId destination = base::Process::Current().Pid();
scoped_refptr<internal::HandleAttachmentWin> attachment(
- new internal::HandleAttachmentWin(handle));
+ new internal::HandleAttachmentWin(handle, HandleWin::DUPLICATE));
AttachmentBrokerMsg_WinHandleHasBeenDuplicated msg(
attachment->GetWireFormat(destination));
AttachmentBrokerUnprivilegedWin attachment_broker;
@@ -40,7 +40,7 @@ TEST(AttachmentBrokerUnprivilegedWinTest, ReceiveInvalidMessage) {
HANDLE handle = LongToHandle(8);
base::ProcessId destination = base::Process::Current().Pid() + 1;
scoped_refptr<internal::HandleAttachmentWin> attachment(
- new internal::HandleAttachmentWin(handle));
+ new internal::HandleAttachmentWin(handle, HandleWin::DUPLICATE));
AttachmentBrokerMsg_WinHandleHasBeenDuplicated msg(
attachment->GetWireFormat(destination));
AttachmentBrokerUnprivilegedWin attachment_broker;
diff --git a/ipc/handle_attachment_win.cc b/ipc/handle_attachment_win.cc
index 994b22d..50e3e6d 100644
--- a/ipc/handle_attachment_win.cc
+++ b/ipc/handle_attachment_win.cc
@@ -9,17 +9,20 @@
namespace IPC {
namespace internal {
-HandleAttachmentWin::HandleAttachmentWin(const HANDLE& handle)
- : handle_(handle) {
-}
+HandleAttachmentWin::HandleAttachmentWin(const HANDLE& handle,
+ HandleWin::Permissions permissions)
+ : handle_(handle), permissions_(permissions) {}
HandleAttachmentWin::HandleAttachmentWin(const WireFormat& wire_format)
: BrokerableAttachment(wire_format.attachment_id, false),
- handle_(LongToHandle(wire_format.handle)) {}
+ handle_(LongToHandle(wire_format.handle)),
+ permissions_(wire_format.permissions) {}
HandleAttachmentWin::HandleAttachmentWin(
const BrokerableAttachment::AttachmentId& id)
- : BrokerableAttachment(id, true), handle_(INVALID_HANDLE_VALUE) {}
+ : BrokerableAttachment(id, true),
+ handle_(INVALID_HANDLE_VALUE),
+ permissions_(HandleWin::INVALID) {}
HandleAttachmentWin::~HandleAttachmentWin() {
}
@@ -48,6 +51,7 @@ HandleAttachmentWin::WireFormat HandleAttachmentWin::GetWireFormat(
format.handle = HandleToLong(handle_);
format.attachment_id = GetIdentifier();
format.destination_process = destination;
+ format.permissions = permissions_;
return format;
}
diff --git a/ipc/handle_attachment_win.h b/ipc/handle_attachment_win.h
index e164cc0..127cd57 100644
--- a/ipc/handle_attachment_win.h
+++ b/ipc/handle_attachment_win.h
@@ -9,6 +9,7 @@
#include "base/process/process_handle.h"
#include "ipc/brokerable_attachment.h"
+#include "ipc/handle_win.h"
#include "ipc/ipc_export.h"
namespace IPC {
@@ -29,10 +30,12 @@ class IPC_EXPORT HandleAttachmentWin : public BrokerableAttachment {
int32_t handle;
// The id of the destination process that the handle is duplicated into.
base::ProcessId destination_process;
+ // The permissions to use when duplicating the handle.
+ HandleWin::Permissions permissions;
AttachmentId attachment_id;
};
- explicit HandleAttachmentWin(const HANDLE& handle);
+ HandleAttachmentWin(const HANDLE& handle, HandleWin::Permissions permissions);
explicit HandleAttachmentWin(const WireFormat& wire_format);
explicit HandleAttachmentWin(const BrokerableAttachment::AttachmentId& id);
@@ -47,6 +50,7 @@ class IPC_EXPORT HandleAttachmentWin : public BrokerableAttachment {
private:
~HandleAttachmentWin() override;
HANDLE handle_;
+ HandleWin::Permissions permissions_;
};
} // namespace internal
diff --git a/ipc/handle_win.cc b/ipc/handle_win.cc
new file mode 100644
index 0000000..ea268bd
--- /dev/null
+++ b/ipc/handle_win.cc
@@ -0,0 +1,53 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ipc/handle_win.h"
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/string_number_conversions.h"
+#include "ipc/handle_attachment_win.h"
+
+namespace IPC {
+
+HandleWin::HandleWin(const HANDLE& handle, Permissions permissions)
+ : handle_(handle), permissions_(permissions) {}
+
+// static
+void ParamTraits<HandleWin>::Write(Message* m, const param_type& p) {
+ scoped_refptr<IPC::internal::HandleAttachmentWin> attachment(
+ new IPC::internal::HandleAttachmentWin(p.get_handle(),
+ p.get_permissions()));
+ if (!m->WriteAttachment(attachment.Pass()))
+ NOTREACHED();
+}
+
+// static
+bool ParamTraits<HandleWin>::Read(const Message* m,
+ base::PickleIterator* iter,
+ param_type* r) {
+ scoped_refptr<MessageAttachment> attachment;
+ if (!m->ReadAttachment(iter, &attachment))
+ return false;
+ if (attachment->GetType() != MessageAttachment::TYPE_BROKERABLE_ATTACHMENT)
+ return false;
+ BrokerableAttachment* brokerable_attachment =
+ static_cast<BrokerableAttachment*>(attachment.get());
+ if (brokerable_attachment->GetBrokerableType() !=
+ BrokerableAttachment::WIN_HANDLE) {
+ return false;
+ }
+ IPC::internal::HandleAttachmentWin* handle_attachment =
+ static_cast<IPC::internal::HandleAttachmentWin*>(brokerable_attachment);
+ r->set_handle(handle_attachment->get_handle());
+ return true;
+}
+
+// static
+void ParamTraits<HandleWin>::Log(const param_type& p, std::string* l) {
+ l->append(base::StringPrintf("0x%X", p.get_handle()));
+ l->append(base::IntToString(p.get_permissions()));
+}
+
+} // namespace IPC
diff --git a/ipc/handle_win.h b/ipc/handle_win.h
new file mode 100644
index 0000000..f5f0263
--- /dev/null
+++ b/ipc/handle_win.h
@@ -0,0 +1,52 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IPC_HANDLE_WIN_H_
+#define IPC_HANDLE_WIN_H_
+
+#include <windows.h>
+
+#include "ipc/ipc_export.h"
+#include "ipc/ipc_message_macros.h"
+
+namespace IPC {
+
+// HandleWin is a wrapper around a Windows HANDLE that can be transported
+// across Chrome IPC channels that support attachment brokering. The HANDLE will
+// be duplicated into the destination process.
+class IPC_EXPORT HandleWin {
+ public:
+ enum Permissions {
+ // A placeholder value to be used by the receiving IPC channel, since the
+ // permissions information is only used by the broker process.
+ INVALID,
+ // The new HANDLE will have the same permissions as the old HANDLE.
+ DUPLICATE,
+ // The new HANDLE will have file read and write permissions.
+ FILE_READ_WRITE,
+ MAX_PERMISSIONS = FILE_READ_WRITE
+ };
+
+ HandleWin(const HANDLE& handle, Permissions permissions);
+
+ HANDLE get_handle() const { return handle_; }
+ void set_handle(HANDLE handle) { handle_ = handle; }
+ Permissions get_permissions() const { return permissions_; }
+
+ private:
+ HANDLE handle_;
+ Permissions permissions_;
+};
+
+template <>
+struct IPC_EXPORT ParamTraits<HandleWin> {
+ typedef HandleWin param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, base::PickleIterator* iter, param_type* p);
+ static void Log(const param_type& p, std::string* l);
+};
+
+} // namespace IPC
+
+#endif // IPC_HANDLE_WIN_H_
diff --git a/ipc/ipc.gypi b/ipc/ipc.gypi
index ce9ffda..beb0a6a 100644
--- a/ipc/ipc.gypi
+++ b/ipc/ipc.gypi
@@ -26,6 +26,8 @@
'brokerable_attachment.h',
'handle_attachment_win.cc',
'handle_attachment_win.h',
+ 'handle_win.cc',
+ 'handle_win.h',
'ipc_channel.cc',
'ipc_channel.h',
'ipc_channel_factory.cc',