xref: /aosp_15_r20/external/cronet/ipc/ipc_message_attachment.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_message_attachment.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/files/scoped_file.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
10*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
11*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_handle_attachment.h"
12*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/platform_handle.h"
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
15*6777b538SAndroid Build Coastguard Worker #include <unistd.h>
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker #include "base/posix/eintr_wrapper.h"
18*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_platform_file_attachment_posix.h"
19*6777b538SAndroid Build Coastguard Worker #endif
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
22*6777b538SAndroid Build Coastguard Worker #include "ipc/mach_port_attachment_mac.h"
23*6777b538SAndroid Build Coastguard Worker #endif
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
26*6777b538SAndroid Build Coastguard Worker #include "ipc/handle_attachment_win.h"
27*6777b538SAndroid Build Coastguard Worker #endif
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
30*6777b538SAndroid Build Coastguard Worker #include "ipc/handle_attachment_fuchsia.h"
31*6777b538SAndroid Build Coastguard Worker #endif
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker namespace IPC {
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker namespace {
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
TakeOrDupFile(internal::PlatformFileAttachment * attachment)38*6777b538SAndroid Build Coastguard Worker base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
39*6777b538SAndroid Build Coastguard Worker   return attachment->Owns()
40*6777b538SAndroid Build Coastguard Worker              ? base::ScopedFD(attachment->TakePlatformFile())
41*6777b538SAndroid Build Coastguard Worker              : base::ScopedFD(HANDLE_EINTR(dup(attachment->file())));
42*6777b538SAndroid Build Coastguard Worker }
43*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker }  // namespace
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker MessageAttachment::MessageAttachment() = default;
48*6777b538SAndroid Build Coastguard Worker 
49*6777b538SAndroid Build Coastguard Worker MessageAttachment::~MessageAttachment() = default;
50*6777b538SAndroid Build Coastguard Worker 
TakeMojoHandle()51*6777b538SAndroid Build Coastguard Worker mojo::ScopedHandle MessageAttachment::TakeMojoHandle() {
52*6777b538SAndroid Build Coastguard Worker   switch (GetType()) {
53*6777b538SAndroid Build Coastguard Worker     case Type::MOJO_HANDLE:
54*6777b538SAndroid Build Coastguard Worker       return static_cast<internal::MojoHandleAttachment*>(this)->TakeHandle();
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
57*6777b538SAndroid Build Coastguard Worker     case Type::PLATFORM_FILE: {
58*6777b538SAndroid Build Coastguard Worker       // We dup() the handles in IPC::Message to transmit.
59*6777b538SAndroid Build Coastguard Worker       // IPC::MessageAttachmentSet has intricate lifetime semantics for FDs, so
60*6777b538SAndroid Build Coastguard Worker       // just to dup()-and-own them is the safest option.
61*6777b538SAndroid Build Coastguard Worker       base::ScopedFD file =
62*6777b538SAndroid Build Coastguard Worker           TakeOrDupFile(static_cast<internal::PlatformFileAttachment*>(this));
63*6777b538SAndroid Build Coastguard Worker       if (!file.is_valid()) {
64*6777b538SAndroid Build Coastguard Worker         DPLOG(WARNING) << "Failed to dup FD to transmit.";
65*6777b538SAndroid Build Coastguard Worker         return mojo::ScopedHandle();
66*6777b538SAndroid Build Coastguard Worker       }
67*6777b538SAndroid Build Coastguard Worker       return mojo::WrapPlatformFile(std::move(file));
68*6777b538SAndroid Build Coastguard Worker     }
69*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
72*6777b538SAndroid Build Coastguard Worker     case Type::MACH_PORT: {
73*6777b538SAndroid Build Coastguard Worker       auto* attachment = static_cast<internal::MachPortAttachmentMac*>(this);
74*6777b538SAndroid Build Coastguard Worker       MojoPlatformHandle platform_handle = {
75*6777b538SAndroid Build Coastguard Worker           sizeof(platform_handle), MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT,
76*6777b538SAndroid Build Coastguard Worker           static_cast<uint64_t>(attachment->get_mach_port())};
77*6777b538SAndroid Build Coastguard Worker       MojoHandle wrapped_handle;
78*6777b538SAndroid Build Coastguard Worker       if (MojoWrapPlatformHandle(&platform_handle, nullptr, &wrapped_handle) !=
79*6777b538SAndroid Build Coastguard Worker           MOJO_RESULT_OK) {
80*6777b538SAndroid Build Coastguard Worker         return mojo::ScopedHandle();
81*6777b538SAndroid Build Coastguard Worker       }
82*6777b538SAndroid Build Coastguard Worker       attachment->reset_mach_port_ownership();
83*6777b538SAndroid Build Coastguard Worker       return mojo::MakeScopedHandle(mojo::Handle(wrapped_handle));
84*6777b538SAndroid Build Coastguard Worker     }
85*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_FUCHSIA)
86*6777b538SAndroid Build Coastguard Worker     case Type::FUCHSIA_HANDLE: {
87*6777b538SAndroid Build Coastguard Worker       auto* attachment = static_cast<internal::HandleAttachmentFuchsia*>(this);
88*6777b538SAndroid Build Coastguard Worker       MojoPlatformHandle platform_handle = {
89*6777b538SAndroid Build Coastguard Worker           sizeof(platform_handle), MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE,
90*6777b538SAndroid Build Coastguard Worker           static_cast<uint64_t>(attachment->Take())};
91*6777b538SAndroid Build Coastguard Worker       MojoHandle wrapped_handle;
92*6777b538SAndroid Build Coastguard Worker       if (MojoWrapPlatformHandle(&platform_handle, nullptr, &wrapped_handle) !=
93*6777b538SAndroid Build Coastguard Worker           MOJO_RESULT_OK) {
94*6777b538SAndroid Build Coastguard Worker         return mojo::ScopedHandle();
95*6777b538SAndroid Build Coastguard Worker       }
96*6777b538SAndroid Build Coastguard Worker       return mojo::MakeScopedHandle(mojo::Handle(wrapped_handle));
97*6777b538SAndroid Build Coastguard Worker     }
98*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_WIN)
99*6777b538SAndroid Build Coastguard Worker     case Type::WIN_HANDLE:
100*6777b538SAndroid Build Coastguard Worker       return mojo::WrapPlatformFile(base::win::ScopedHandle(
101*6777b538SAndroid Build Coastguard Worker           static_cast<internal::HandleAttachmentWin*>(this)->Take()));
102*6777b538SAndroid Build Coastguard Worker #endif
103*6777b538SAndroid Build Coastguard Worker     default:
104*6777b538SAndroid Build Coastguard Worker       break;
105*6777b538SAndroid Build Coastguard Worker   }
106*6777b538SAndroid Build Coastguard Worker   NOTREACHED();
107*6777b538SAndroid Build Coastguard Worker   return mojo::ScopedHandle();
108*6777b538SAndroid Build Coastguard Worker }
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker // static
CreateFromMojoHandle(mojo::ScopedHandle handle,Type type)111*6777b538SAndroid Build Coastguard Worker scoped_refptr<MessageAttachment> MessageAttachment::CreateFromMojoHandle(
112*6777b538SAndroid Build Coastguard Worker     mojo::ScopedHandle handle,
113*6777b538SAndroid Build Coastguard Worker     Type type) {
114*6777b538SAndroid Build Coastguard Worker   if (type == Type::MOJO_HANDLE)
115*6777b538SAndroid Build Coastguard Worker     return new internal::MojoHandleAttachment(std::move(handle));
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker   MojoPlatformHandle platform_handle = {sizeof(platform_handle), 0, 0};
118*6777b538SAndroid Build Coastguard Worker   MojoResult unwrap_result = MojoUnwrapPlatformHandle(
119*6777b538SAndroid Build Coastguard Worker       handle.release().value(), nullptr, &platform_handle);
120*6777b538SAndroid Build Coastguard Worker   if (unwrap_result != MOJO_RESULT_OK)
121*6777b538SAndroid Build Coastguard Worker     return nullptr;
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
124*6777b538SAndroid Build Coastguard Worker   if (type == Type::PLATFORM_FILE) {
125*6777b538SAndroid Build Coastguard Worker     base::PlatformFile file = base::kInvalidPlatformFile;
126*6777b538SAndroid Build Coastguard Worker     if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR)
127*6777b538SAndroid Build Coastguard Worker       file = static_cast<base::PlatformFile>(platform_handle.value);
128*6777b538SAndroid Build Coastguard Worker     return new internal::PlatformFileAttachment(file);
129*6777b538SAndroid Build Coastguard Worker   }
130*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
133*6777b538SAndroid Build Coastguard Worker   if (type == Type::MACH_PORT) {
134*6777b538SAndroid Build Coastguard Worker     mach_port_t mach_port = MACH_PORT_NULL;
135*6777b538SAndroid Build Coastguard Worker     if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT)
136*6777b538SAndroid Build Coastguard Worker       mach_port = static_cast<mach_port_t>(platform_handle.value);
137*6777b538SAndroid Build Coastguard Worker     return new internal::MachPortAttachmentMac(
138*6777b538SAndroid Build Coastguard Worker         mach_port, internal::MachPortAttachmentMac::FROM_WIRE);
139*6777b538SAndroid Build Coastguard Worker   }
140*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_FUCHSIA)
141*6777b538SAndroid Build Coastguard Worker   if (type == Type::FUCHSIA_HANDLE) {
142*6777b538SAndroid Build Coastguard Worker     zx::handle zx_handle;
143*6777b538SAndroid Build Coastguard Worker     if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE)
144*6777b538SAndroid Build Coastguard Worker       zx_handle.reset(static_cast<zx_handle_t>(platform_handle.value));
145*6777b538SAndroid Build Coastguard Worker     return new internal::HandleAttachmentFuchsia(std::move(zx_handle));
146*6777b538SAndroid Build Coastguard Worker   }
147*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_WIN)
148*6777b538SAndroid Build Coastguard Worker   if (type == Type::WIN_HANDLE) {
149*6777b538SAndroid Build Coastguard Worker     base::PlatformFile platform_file = base::kInvalidPlatformFile;
150*6777b538SAndroid Build Coastguard Worker     if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE) {
151*6777b538SAndroid Build Coastguard Worker       platform_file =
152*6777b538SAndroid Build Coastguard Worker           reinterpret_cast<base::PlatformFile>(platform_handle.value);
153*6777b538SAndroid Build Coastguard Worker     }
154*6777b538SAndroid Build Coastguard Worker     return new internal::HandleAttachmentWin(
155*6777b538SAndroid Build Coastguard Worker         platform_file, internal::HandleAttachmentWin::FROM_WIRE);
156*6777b538SAndroid Build Coastguard Worker   }
157*6777b538SAndroid Build Coastguard Worker #endif
158*6777b538SAndroid Build Coastguard Worker   NOTREACHED();
159*6777b538SAndroid Build Coastguard Worker   return nullptr;
160*6777b538SAndroid Build Coastguard Worker }
161*6777b538SAndroid Build Coastguard Worker 
162*6777b538SAndroid Build Coastguard Worker }  // namespace IPC
163