Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: components/nacl/browser/nacl_process_host.cc

Issue 2301103003: Use ChannelMojo for NaCl PPAPI channels. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/nacl/browser/nacl_process_host.h" 5 #include "components/nacl/browser/nacl_process_host.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 204
205 void CloseFile(base::File file) { 205 void CloseFile(base::File file) {
206 // The base::File destructor will close the file for us. 206 // The base::File destructor will close the file for us.
207 } 207 }
208 208
209 } // namespace 209 } // namespace
210 210
211 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = 211 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ =
212 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds; 212 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds;
213 213
214 // Unfortunately, we cannot use ScopedGeneric directly for IPC::ChannelHandle,
215 // because there is neither operator== nor operator != definition for it.
216 // Instead, define a simple wrapper for IPC::ChannelHandle with an assumption
217 // that this only takes a transferred IPC::ChannelHandle or one to be
218 // transferred via IPC.
219 class NaClProcessHost::ScopedChannelHandle {
220 public:
221 ScopedChannelHandle() {
222 }
223 explicit ScopedChannelHandle(const IPC::ChannelHandle& handle)
224 : handle_(handle) {
225 DCHECK(IsSupportedHandle(handle_));
226 }
227 ScopedChannelHandle(ScopedChannelHandle&& other) : handle_(other.handle_) {
228 other.handle_ = IPC::ChannelHandle();
229 DCHECK(IsSupportedHandle(handle_));
230 }
231 ~ScopedChannelHandle() {
232 CloseIfNecessary();
233 }
234
235 const IPC::ChannelHandle& get() const { return handle_; }
236 IPC::ChannelHandle release() WARN_UNUSED_RESULT {
237 IPC::ChannelHandle result = handle_;
238 handle_ = IPC::ChannelHandle();
239 return result;
240 }
241
242 void reset(const IPC::ChannelHandle& handle = IPC::ChannelHandle()) {
243 DCHECK(IsSupportedHandle(handle));
244 #if defined(OS_POSIX)
245 // Following the manner of base::ScopedGeneric, we do not support
246 // reset() with same handle for simplicity of the implementation.
247 CHECK(handle.socket.fd == -1 || handle.socket.fd != handle_.socket.fd);
248 #endif
249 CloseIfNecessary();
250 handle_ = handle;
251 }
252
253 private:
254 // Returns true if the given handle is closable automatically by this
255 // class. This function is just a helper for validation.
256 static bool IsSupportedHandle(const IPC::ChannelHandle& handle) {
257 #if defined(OS_WIN)
258 // On Windows, it is not supported to marshal the |pipe.handle|.
259 // In our case, we wrap a transferred ChannelHandle (or one to be
260 // transferred) via IPC, so we can assume |handle.pipe.handle| is NULL.
261 return handle.pipe.handle == NULL;
262 #else
263 return true;
264 #endif
265 }
266
267 void CloseIfNecessary() {
268 #if defined(OS_POSIX)
269 if (handle_.socket.auto_close) {
270 // Defer closing task to the ScopedFD.
271 base::ScopedFD(handle_.socket.fd);
272 }
273 #endif
274 }
275
276 IPC::ChannelHandle handle_;
277
278 DISALLOW_COPY_AND_ASSIGN(ScopedChannelHandle);
279 };
280
281 NaClProcessHost::NaClProcessHost( 214 NaClProcessHost::NaClProcessHost(
282 const GURL& manifest_url, 215 const GURL& manifest_url,
283 base::File nexe_file, 216 base::File nexe_file,
284 const NaClFileToken& nexe_token, 217 const NaClFileToken& nexe_token,
285 const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, 218 const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files,
286 ppapi::PpapiPermissions permissions, 219 ppapi::PpapiPermissions permissions,
287 int render_view_id, 220 int render_view_id,
288 uint32_t permission_bits, 221 uint32_t permission_bits,
289 bool uses_nonsfi_mode, 222 bool uses_nonsfi_mode,
290 bool off_the_record, 223 bool off_the_record,
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 647 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
715 if (!nacl_browser->IsReady()) { 648 if (!nacl_browser->IsReady()) {
716 SendErrorToRenderer("could not acquire shared resources needed by NaCl"); 649 SendErrorToRenderer("could not acquire shared resources needed by NaCl");
717 delete this; 650 delete this;
718 } else if (!StartNaClExecution()) { 651 } else if (!StartNaClExecution()) {
719 delete this; 652 delete this;
720 } 653 }
721 } 654 }
722 655
723 void NaClProcessHost::ReplyToRenderer( 656 void NaClProcessHost::ReplyToRenderer(
724 ScopedChannelHandle ppapi_channel_handle, 657 mojo::ScopedMessagePipeHandle ppapi_channel_handle,
725 ScopedChannelHandle trusted_channel_handle, 658 mojo::ScopedMessagePipeHandle trusted_channel_handle,
726 ScopedChannelHandle manifest_service_channel_handle) { 659 mojo::ScopedMessagePipeHandle manifest_service_channel_handle) {
727 // Hereafter, we always send an IPC message with handles created above 660 // Hereafter, we always send an IPC message with handles created above
728 // which, on Windows, are not closable in this process. 661 // which, on Windows, are not closable in this process.
729 std::string error_message; 662 std::string error_message;
730 base::SharedMemoryHandle crash_info_shmem_renderer_handle; 663 base::SharedMemoryHandle crash_info_shmem_renderer_handle;
731 if (!crash_info_shmem_.ShareToProcess(nacl_host_message_filter_->PeerHandle(), 664 if (!crash_info_shmem_.ShareToProcess(nacl_host_message_filter_->PeerHandle(),
732 &crash_info_shmem_renderer_handle)) { 665 &crash_info_shmem_renderer_handle)) {
733 // On error, we do not send "IPC::ChannelHandle"s to the renderer process. 666 // On error, we do not send "IPC::ChannelHandle"s to the renderer process.
734 // Note that some other FDs/handles still get sent to the renderer, but 667 // Note that some other FDs/handles still get sent to the renderer, but
735 // will be closed there. 668 // will be closed there.
736 ppapi_channel_handle.reset(); 669 ppapi_channel_handle.reset();
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 } else { 894 } else {
962 params.nexe_file = IPC::TakePlatformFileForTransit(std::move(nexe_file_)); 895 params.nexe_file = IPC::TakePlatformFileForTransit(std::move(nexe_file_));
963 } 896 }
964 897
965 #if defined(OS_LINUX) 898 #if defined(OS_LINUX)
966 // In Non-SFI mode, create socket pairs for IPC channels here, unlike in 899 // In Non-SFI mode, create socket pairs for IPC channels here, unlike in
967 // SFI-mode, in which those channels are created in nacl_listener.cc. 900 // SFI-mode, in which those channels are created in nacl_listener.cc.
968 // This is for security hardening. We can then prohibit the socketpair() 901 // This is for security hardening. We can then prohibit the socketpair()
969 // system call in nacl_helper and nacl_helper_nonsfi. 902 // system call in nacl_helper and nacl_helper_nonsfi.
970 if (uses_nonsfi_mode_) { 903 if (uses_nonsfi_mode_) {
971 // Note: here, because some FDs/handles for the NaCl loader process are 904 // Note: here, because some FDs/handles for the NaCl loader process are
Mark Seaborn 2016/10/17 21:28:26 I think you can remove this comment, since you rem
Sam McNally 2016/10/17 23:01:17 Done.
972 // already opened, they are transferred to NaCl loader process even if 905 // already opened, they are transferred to NaCl loader process even if
973 // an error occurs first. It is because this is the simplest way to 906 // an error occurs first. It is because this is the simplest way to
974 // ensure that these FDs/handles don't get leaked and that the NaCl loader 907 // ensure that these FDs/handles don't get leaked and that the NaCl loader
975 // process will exit properly. 908 // process will exit properly.
976 bool has_error = false;
977 909
978 ScopedChannelHandle ppapi_browser_server_channel_handle; 910 mojo::MessagePipe ppapi_browser_channel;
979 ScopedChannelHandle ppapi_browser_client_channel_handle; 911 mojo::MessagePipe ppapi_renderer_channel;
980 ScopedChannelHandle ppapi_renderer_server_channel_handle; 912 mojo::MessagePipe trusted_service_channel;
981 ScopedChannelHandle ppapi_renderer_client_channel_handle; 913 mojo::MessagePipe manifest_service_channel;
982 ScopedChannelHandle trusted_service_server_channel_handle;
983 ScopedChannelHandle trusted_service_client_channel_handle;
984 ScopedChannelHandle manifest_service_server_channel_handle;
985 ScopedChannelHandle manifest_service_client_channel_handle;
986 914
987 if (!CreateChannelHandlePair(&ppapi_browser_server_channel_handle, 915 if (!StartPPAPIProxy(std::move(ppapi_browser_channel.handle1))) {
988 &ppapi_browser_client_channel_handle) || 916 SendErrorToRenderer("Failed to start browser PPAPI proxy.");
989 !CreateChannelHandlePair(&ppapi_renderer_server_channel_handle, 917 return;
990 &ppapi_renderer_client_channel_handle) ||
991 !CreateChannelHandlePair(&trusted_service_server_channel_handle,
992 &trusted_service_client_channel_handle) ||
993 !CreateChannelHandlePair(&manifest_service_server_channel_handle,
994 &manifest_service_client_channel_handle)) {
995 SendErrorToRenderer("Failed to create socket pairs.");
996 has_error = true;
997 } 918 }
998 919
999 if (!has_error && 920 // On success, send back a success message to the renderer process,
1000 !StartPPAPIProxy(std::move(ppapi_browser_client_channel_handle))) { 921 // and transfer the channel handles for the NaCl loader process to
1001 SendErrorToRenderer("Failed to start browser PPAPI proxy."); 922 // |params|.
1002 has_error = true; 923 ReplyToRenderer(std::move(ppapi_renderer_channel.handle1),
1003 } 924 std::move(trusted_service_channel.handle1),
1004 925 std::move(manifest_service_channel.handle1));
1005 if (!has_error) { 926 params.ppapi_browser_channel_handle =
1006 // On success, send back a success message to the renderer process, 927 ppapi_browser_channel.handle0.release();
1007 // and transfer the channel handles for the NaCl loader process to 928 params.ppapi_renderer_channel_handle =
1008 // |params|. 929 ppapi_renderer_channel.handle0.release();
1009 ReplyToRenderer(std::move(ppapi_renderer_client_channel_handle), 930 params.trusted_service_channel_handle =
1010 std::move(trusted_service_client_channel_handle), 931 trusted_service_channel.handle0.release();
1011 std::move(manifest_service_client_channel_handle)); 932 params.manifest_service_channel_handle =
1012 params.ppapi_browser_channel_handle = 933 manifest_service_channel.handle0.release();
1013 ppapi_browser_server_channel_handle.release();
1014 params.ppapi_renderer_channel_handle =
1015 ppapi_renderer_server_channel_handle.release();
1016 params.trusted_service_channel_handle =
1017 trusted_service_server_channel_handle.release();
1018 params.manifest_service_channel_handle =
1019 manifest_service_server_channel_handle.release();
1020 }
1021 } 934 }
1022 #endif 935 #endif
1023 936
1024 process_->Send(new NaClProcessMsg_Start(params)); 937 process_->Send(new NaClProcessMsg_Start(params));
1025 } 938 }
1026 939
1027 #if defined(OS_LINUX) 940 bool NaClProcessHost::StartPPAPIProxy(
1028 // static 941 mojo::ScopedMessagePipeHandle channel_handle) {
1029 bool NaClProcessHost::CreateChannelHandlePair(
1030 ScopedChannelHandle* channel_handle1,
1031 ScopedChannelHandle* channel_handle2) {
1032 DCHECK(channel_handle1);
1033 DCHECK(channel_handle2);
1034
1035 int fd1 = -1;
1036 int fd2 = -1;
1037 if (!IPC::SocketPair(&fd1, &fd2)) {
1038 return false;
1039 }
1040
1041 IPC::ChannelHandle handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
1042 handle.socket = base::FileDescriptor(fd1, true);
1043 channel_handle1->reset(handle);
1044 handle.socket = base::FileDescriptor(fd2, true);
1045 channel_handle2->reset(handle);
1046 return true;
1047 }
1048 #endif
1049
1050 bool NaClProcessHost::StartPPAPIProxy(ScopedChannelHandle channel_handle) {
1051 if (ipc_proxy_channel_.get()) { 942 if (ipc_proxy_channel_.get()) {
1052 // Attempt to open more than 1 browser channel is not supported. 943 // Attempt to open more than 1 browser channel is not supported.
1053 // Shut down the NaCl process. 944 // Shut down the NaCl process.
1054 process_->GetHost()->ForceShutdown(); 945 process_->GetHost()->ForceShutdown();
1055 return false; 946 return false;
1056 } 947 }
1057 948
1058 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); 949 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type);
1059 950
1060 ipc_proxy_channel_ = IPC::ChannelProxy::Create( 951 ipc_proxy_channel_ = IPC::ChannelProxy::Create(
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 return true; 993 return true;
1103 } 994 }
1104 995
1105 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is 996 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is
1106 // received. 997 // received.
1107 void NaClProcessHost::OnPpapiChannelsCreated( 998 void NaClProcessHost::OnPpapiChannelsCreated(
1108 const IPC::ChannelHandle& raw_ppapi_browser_channel_handle, 999 const IPC::ChannelHandle& raw_ppapi_browser_channel_handle,
1109 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle, 1000 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle,
1110 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle, 1001 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle,
1111 const IPC::ChannelHandle& raw_manifest_service_channel_handle) { 1002 const IPC::ChannelHandle& raw_manifest_service_channel_handle) {
1112 ScopedChannelHandle ppapi_browser_channel_handle( 1003 DCHECK(raw_ppapi_browser_channel_handle.is_mojo_channel_handle());
1113 raw_ppapi_browser_channel_handle); 1004 DCHECK(raw_ppapi_renderer_channel_handle.is_mojo_channel_handle());
1114 ScopedChannelHandle ppapi_renderer_channel_handle( 1005 DCHECK(raw_trusted_renderer_channel_handle.is_mojo_channel_handle());
1115 raw_ppapi_renderer_channel_handle); 1006 DCHECK(raw_manifest_service_channel_handle.is_mojo_channel_handle());
1116 ScopedChannelHandle trusted_renderer_channel_handle( 1007
1117 raw_trusted_renderer_channel_handle); 1008 mojo::ScopedMessagePipeHandle ppapi_browser_channel_handle(
1118 ScopedChannelHandle manifest_service_channel_handle( 1009 raw_ppapi_browser_channel_handle.mojo_handle);
1119 raw_manifest_service_channel_handle); 1010 mojo::ScopedMessagePipeHandle ppapi_renderer_channel_handle(
1011 raw_ppapi_renderer_channel_handle.mojo_handle);
1012 mojo::ScopedMessagePipeHandle trusted_renderer_channel_handle(
1013 raw_trusted_renderer_channel_handle.mojo_handle);
1014 mojo::ScopedMessagePipeHandle manifest_service_channel_handle(
1015 raw_manifest_service_channel_handle.mojo_handle);
1120 1016
1121 if (!StartPPAPIProxy(std::move(ppapi_browser_channel_handle))) { 1017 if (!StartPPAPIProxy(std::move(ppapi_browser_channel_handle))) {
1122 SendErrorToRenderer("Browser PPAPI proxy could not start."); 1018 SendErrorToRenderer("Browser PPAPI proxy could not start.");
1123 return; 1019 return;
1124 } 1020 }
1125 1021
1126 // Let the renderer know that the IPC channels are established. 1022 // Let the renderer know that the IPC channels are established.
1127 ReplyToRenderer(std::move(ppapi_renderer_channel_handle), 1023 ReplyToRenderer(std::move(ppapi_renderer_channel_handle),
1128 std::move(trusted_renderer_channel_handle), 1024 std::move(trusted_renderer_channel_handle),
1129 std::move(manifest_service_channel_handle)); 1025 std::move(manifest_service_channel_handle));
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 NaClStartDebugExceptionHandlerThread( 1193 NaClStartDebugExceptionHandlerThread(
1298 std::move(process), info, base::ThreadTaskRunnerHandle::Get(), 1194 std::move(process), info, base::ThreadTaskRunnerHandle::Get(),
1299 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 1195 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
1300 weak_factory_.GetWeakPtr())); 1196 weak_factory_.GetWeakPtr()));
1301 return true; 1197 return true;
1302 } 1198 }
1303 } 1199 }
1304 #endif 1200 #endif
1305 1201
1306 } // namespace nacl 1202 } // namespace nacl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698