1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ipc/attachment_broker_privileged_win.h"
9 #include "base/process/process.h"
10 #include "ipc/attachment_broker_messages.h"
11 #include "ipc/brokerable_attachment.h"
12 #include "ipc/handle_attachment_win.h"
13 #include "ipc/ipc_channel.h"
17 AttachmentBrokerPrivilegedWin::AttachmentBrokerPrivilegedWin() {}
19 AttachmentBrokerPrivilegedWin::~AttachmentBrokerPrivilegedWin() {}
21 bool AttachmentBrokerPrivilegedWin::SendAttachmentToProcess(
22 const BrokerableAttachment
* attachment
,
23 base::ProcessId destination_process
) {
24 switch (attachment
->GetBrokerableType()) {
25 case BrokerableAttachment::WIN_HANDLE
:
26 const internal::HandleAttachmentWin
* handle_attachment
=
27 static_cast<const internal::HandleAttachmentWin
*>(attachment
);
28 HandleWireFormat wire_format
=
29 handle_attachment
->GetWireFormat(destination_process
);
30 HandleWireFormat new_wire_format
=
31 DuplicateWinHandle(wire_format
, base::Process::Current().Pid());
32 if (new_wire_format
.handle
== 0)
34 RouteDuplicatedHandle(new_wire_format
);
40 bool AttachmentBrokerPrivilegedWin::OnMessageReceived(const Message
& msg
) {
43 IPC_MESSAGE_HANDLER_GENERIC(AttachmentBrokerMsg_DuplicateWinHandle
,
44 OnDuplicateWinHandle(msg
))
45 IPC_MESSAGE_UNHANDLED(handled
= false)
50 void AttachmentBrokerPrivilegedWin::OnDuplicateWinHandle(
51 const IPC::Message
& message
) {
52 AttachmentBrokerMsg_DuplicateWinHandle::Param param
;
53 if (!AttachmentBrokerMsg_DuplicateWinHandle::Read(&message
, ¶m
))
55 IPC::internal::HandleAttachmentWin::WireFormat wire_format
=
58 if (wire_format
.destination_process
== base::kNullProcessId
)
61 HandleWireFormat new_wire_format
=
62 DuplicateWinHandle(wire_format
, message
.get_sender_pid());
63 RouteDuplicatedHandle(new_wire_format
);
66 void AttachmentBrokerPrivilegedWin::RouteDuplicatedHandle(
67 const HandleWireFormat
& wire_format
) {
68 // This process is the destination.
69 if (wire_format
.destination_process
== base::Process::Current().Pid()) {
70 scoped_refptr
<BrokerableAttachment
> attachment(
71 new internal::HandleAttachmentWin(wire_format
));
72 HandleReceivedAttachment(attachment
);
76 // Another process is the destination.
77 base::ProcessId dest
= wire_format
.destination_process
;
78 Channel
* channel
= GetChannelWithProcessId(dest
);
80 // Assuming that this message was not sent from a malicious process, the
81 // channel endpoint that would have received this message will block
83 LOG(ERROR
) << "Failed to deliver brokerable attachment to process with id: "
89 new AttachmentBrokerMsg_WinHandleHasBeenDuplicated(wire_format
));
92 AttachmentBrokerPrivilegedWin::HandleWireFormat
93 AttachmentBrokerPrivilegedWin::DuplicateWinHandle(
94 const HandleWireFormat
& wire_format
,
95 base::ProcessId source_pid
) {
96 HandleWireFormat new_wire_format
;
97 new_wire_format
.destination_process
= wire_format
.destination_process
;
98 new_wire_format
.attachment_id
= wire_format
.attachment_id
;
100 HANDLE original_handle
= LongToHandle(wire_format
.handle
);
102 base::Process source_process
=
103 base::Process::OpenWithExtraPrivileges(source_pid
);
104 base::Process dest_process
=
105 base::Process::OpenWithExtraPrivileges(wire_format
.destination_process
);
106 if (source_process
.Handle() && dest_process
.Handle()) {
108 DWORD result
= ::DuplicateHandle(source_process
.Handle(), original_handle
,
109 dest_process
.Handle(), &new_handle
, 0,
110 FALSE
, DUPLICATE_SAME_ACCESS
);
112 new_wire_format
.handle
= (result
!= 0) ? HandleToLong(new_handle
) : 0;
114 new_wire_format
.handle
= 0;
116 return new_wire_format
;