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

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

Issue 1051243002: Non-SFI: move socketpair() from plugin process to browser process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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
« no previous file with comments | « components/nacl/browser/nacl_process_host.h ('k') | components/nacl/common/nacl_messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 bool nonsfi_mode_enabled = 467 bool nonsfi_mode_enabled =
468 nonsfi_mode_forced_by_command_line || nonsfi_mode_allowed; 468 nonsfi_mode_forced_by_command_line || nonsfi_mode_allowed;
469 469
470 if (!nonsfi_mode_enabled) { 470 if (!nonsfi_mode_enabled) {
471 SendErrorToRenderer( 471 SendErrorToRenderer(
472 "NaCl non-SFI mode is not available for this platform" 472 "NaCl non-SFI mode is not available for this platform"
473 " and NaCl module."); 473 " and NaCl module.");
474 delete this; 474 delete this;
475 return; 475 return;
476 } 476 }
477
478 if (!enable_ppapi_proxy()) {
479 SendErrorToRenderer(
480 "PPAPI proxy must be enabled on NaCl in Non-SFI mode.");
481 delete this;
482 return;
483 }
477 } else { 484 } else {
478 // Rather than creating a socket pair in the renderer, and passing 485 // Rather than creating a socket pair in the renderer, and passing
479 // one side through the browser to sel_ldr, socket pairs are created 486 // one side through the browser to sel_ldr, socket pairs are created
480 // in the browser and then passed to the renderer and sel_ldr. 487 // in the browser and then passed to the renderer and sel_ldr.
481 // 488 //
482 // This is mainly for the benefit of Windows, where sockets cannot 489 // This is mainly for the benefit of Windows, where sockets cannot
483 // be passed in messages, but are copied via DuplicateHandle(). 490 // be passed in messages, but are copied via DuplicateHandle().
484 // This means the sandboxed renderer cannot send handles to the 491 // This means the sandboxed renderer cannot send handles to the
485 // browser process. 492 // browser process.
486 493
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 } 672 }
666 #endif 673 #endif
667 process_->Launch( 674 process_->Launch(
668 new NaClSandboxedProcessLauncherDelegate(process_->GetHost()), 675 new NaClSandboxedProcessLauncherDelegate(process_->GetHost()),
669 cmd_line.release(), 676 cmd_line.release(),
670 true); 677 true);
671 return true; 678 return true;
672 } 679 }
673 680
674 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { 681 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
675 bool handled = true;
676 if (uses_nonsfi_mode_) { 682 if (uses_nonsfi_mode_) {
677 // IPC messages relating to NaCl's validation cache must not be exposed 683 // IPC messages relating to NaCl's validation cache must not be exposed
678 // in Non-SFI Mode, otherwise a Non-SFI nexe could use 684 // in Non-SFI Mode, otherwise a Non-SFI nexe could use SetKnownToValidate
679 // SetKnownToValidate to create a hole in the SFI sandbox. 685 // to create a hole in the SFI sandbox.
680 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) 686 // In Non-SFI mode, no message is expected.
681 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, 687 return false;
682 OnPpapiChannelsCreated) 688 }
683 IPC_MESSAGE_UNHANDLED(handled = false) 689
684 IPC_END_MESSAGE_MAP() 690 bool handled = true;
685 } else { 691 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg)
686 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) 692 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate,
687 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, 693 OnQueryKnownToValidate)
688 OnQueryKnownToValidate) 694 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate,
689 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, 695 OnSetKnownToValidate)
690 OnSetKnownToValidate) 696 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileToken,
691 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileToken, 697 OnResolveFileToken)
692 OnResolveFileToken)
693 698
694 #if defined(OS_WIN) 699 #if defined(OS_WIN)
695 IPC_MESSAGE_HANDLER_DELAY_REPLY( 700 IPC_MESSAGE_HANDLER_DELAY_REPLY(
696 NaClProcessMsg_AttachDebugExceptionHandler, 701 NaClProcessMsg_AttachDebugExceptionHandler,
697 OnAttachDebugExceptionHandler) 702 OnAttachDebugExceptionHandler)
698 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected, 703 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected,
699 OnDebugStubPortSelected) 704 OnDebugStubPortSelected)
700 #endif 705 #endif
701 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, 706 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated,
702 OnPpapiChannelsCreated) 707 OnPpapiChannelsCreated)
703 IPC_MESSAGE_UNHANDLED(handled = false) 708 IPC_MESSAGE_UNHANDLED(handled = false)
704 IPC_END_MESSAGE_MAP() 709 IPC_END_MESSAGE_MAP()
705 }
706 return handled; 710 return handled;
707 } 711 }
708 712
709 void NaClProcessHost::OnProcessLaunched() { 713 void NaClProcessHost::OnProcessLaunched() {
710 if (!StartWithLaunchedProcess()) 714 if (!StartWithLaunchedProcess())
711 delete this; 715 delete this;
712 } 716 }
713 717
714 // Called when the NaClBrowser singleton has been fully initialized. 718 // Called when the NaClBrowser singleton has been fully initialized.
715 void NaClProcessHost::OnResourcesReady() { 719 void NaClProcessHost::OnResourcesReady() {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 true /* is_executable */), 972 true /* is_executable */),
969 base::Bind(&NaClProcessHost::StartNaClFileResolved, 973 base::Bind(&NaClProcessHost::StartNaClFileResolved,
970 weak_factory_.GetWeakPtr(), 974 weak_factory_.GetWeakPtr(),
971 params, 975 params,
972 file_path))) { 976 file_path))) {
973 return true; 977 return true;
974 } 978 }
975 } 979 }
976 } 980 }
977 981
978 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), 982 StartNaClFileResolved(params, base::FilePath(), base::File());
979 process_->GetData().handle);
980 process_->Send(new NaClProcessMsg_Start(params));
981 return true; 983 return true;
982 } 984 }
983 985
984 void NaClProcessHost::StartNaClFileResolved( 986 void NaClProcessHost::StartNaClFileResolved(
985 NaClStartParams params, 987 NaClStartParams params,
986 const base::FilePath& file_path, 988 const base::FilePath& file_path,
987 base::File checked_nexe_file) { 989 base::File checked_nexe_file) {
988 if (checked_nexe_file.IsValid()) { 990 if (checked_nexe_file.IsValid()) {
989 // Release the file received from the renderer. This has to be done on a 991 // Release the file received from the renderer. This has to be done on a
990 // thread where IO is permitted, though. 992 // thread where IO is permitted, though.
991 content::BrowserThread::GetBlockingPool()->PostTask( 993 content::BrowserThread::GetBlockingPool()->PostTask(
992 FROM_HERE, 994 FROM_HERE,
993 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); 995 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass())));
994 params.nexe_file_path_metadata = file_path; 996 params.nexe_file_path_metadata = file_path;
995 params.nexe_file = IPC::TakeFileHandleForProcess( 997 params.nexe_file = IPC::TakeFileHandleForProcess(
996 checked_nexe_file.Pass(), process_->GetData().handle); 998 checked_nexe_file.Pass(), process_->GetData().handle);
997 } else { 999 } else {
998 params.nexe_file = IPC::TakeFileHandleForProcess( 1000 params.nexe_file = IPC::TakeFileHandleForProcess(
999 nexe_file_.Pass(), process_->GetData().handle); 1001 nexe_file_.Pass(), process_->GetData().handle);
1000 } 1002 }
1003
1004 #if defined(OS_LINUX)
1005 // In Non-SFI mode, create socket pairs for IPC channels here, unlike in
1006 // SFI-mode, in which those channels are created in nacl_listener.cc.
1007 // This is for security hardening. We can then prohibit the socketpair()
1008 // system call in nacl_helper and nacl_helper_nonsfi.
1009 if (uses_nonsfi_mode_) {
1010 // Note: here, because some FDs/handles for the NaCl loader process are
1011 // already opened, they are transferred to NaCl loader process even if
1012 // an error occurs first. It is because this is the simplest way to
1013 // ensure that these FDs/handles don't get leaked and that the NaCl loader
1014 // process will exit properly.
1015 bool has_error = false;
1016
1017 // Note: this check is redundant. We check this earlier.
1018 DCHECK(params.enable_ipc_proxy);
1019
1020 ScopedChannelHandle ppapi_browser_server_channel_handle;
1021 ScopedChannelHandle ppapi_browser_client_channel_handle;
1022 ScopedChannelHandle ppapi_renderer_server_channel_handle;
1023 ScopedChannelHandle ppapi_renderer_client_channel_handle;
1024 ScopedChannelHandle trusted_service_server_channel_handle;
1025 ScopedChannelHandle trusted_service_client_channel_handle;
1026 ScopedChannelHandle manifest_service_server_channel_handle;
1027 ScopedChannelHandle manifest_service_client_channel_handle;
1028
1029 if (!CreateChannelHandlePair(&ppapi_browser_server_channel_handle,
1030 &ppapi_browser_client_channel_handle) ||
1031 !CreateChannelHandlePair(&ppapi_renderer_server_channel_handle,
1032 &ppapi_renderer_client_channel_handle) ||
1033 !CreateChannelHandlePair(&trusted_service_server_channel_handle,
1034 &trusted_service_client_channel_handle) ||
1035 !CreateChannelHandlePair(&manifest_service_server_channel_handle,
1036 &manifest_service_client_channel_handle)) {
1037 SendErrorToRenderer("Failed to create socket pairs.");
1038 has_error = true;
1039 }
1040
1041 if (!has_error &&
1042 !StartPPAPIProxy(ppapi_browser_client_channel_handle.Pass())) {
1043 SendErrorToRenderer("Failed to start browser PPAPI proxy.");
1044 has_error = true;
1045 }
1046
1047 if (!has_error) {
1048 // On success, send back a success message to the renderer process,
1049 // and transfer the channel handles for the NaCl loader process to
1050 // |params|.
1051 ReplyToRenderer(ppapi_renderer_client_channel_handle.Pass(),
1052 trusted_service_client_channel_handle.Pass(),
1053 manifest_service_client_channel_handle.Pass());
1054 params.ppapi_browser_channel_handle =
1055 ppapi_browser_server_channel_handle.release();
1056 params.ppapi_renderer_channel_handle =
1057 ppapi_renderer_server_channel_handle.release();
1058 params.trusted_service_channel_handle =
1059 trusted_service_server_channel_handle.release();
1060 params.manifest_service_channel_handle =
1061 manifest_service_server_channel_handle.release();
1062 }
1063 }
1064 #endif
1065
1001 process_->Send(new NaClProcessMsg_Start(params)); 1066 process_->Send(new NaClProcessMsg_Start(params));
1002 } 1067 }
1003 1068
1004 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is 1069 #if defined(OS_LINUX)
1005 // received. 1070 // static
1006 void NaClProcessHost::OnPpapiChannelsCreated( 1071 bool NaClProcessHost::CreateChannelHandlePair(
1007 const IPC::ChannelHandle& raw_browser_channel_handle, 1072 ScopedChannelHandle* channel_handle1,
1008 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle, 1073 ScopedChannelHandle* channel_handle2) {
1009 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle, 1074 DCHECK(channel_handle1);
1010 const IPC::ChannelHandle& raw_manifest_service_channel_handle) { 1075 DCHECK(channel_handle2);
1011 ScopedChannelHandle browser_channel_handle(raw_browser_channel_handle);
1012 ScopedChannelHandle ppapi_renderer_channel_handle(
1013 raw_ppapi_renderer_channel_handle);
1014 ScopedChannelHandle trusted_renderer_channel_handle(
1015 raw_trusted_renderer_channel_handle);
1016 ScopedChannelHandle manifest_service_channel_handle(
1017 raw_manifest_service_channel_handle);
1018 1076
1019 if (!enable_ppapi_proxy()) { 1077 int fd1 = -1;
1020 ReplyToRenderer(ScopedChannelHandle(), 1078 int fd2 = -1;
1021 trusted_renderer_channel_handle.Pass(), 1079 if (!IPC::SocketPair(&fd1, &fd2)) {
1022 manifest_service_channel_handle.Pass()); 1080 return false;
1023 return;
1024 } 1081 }
1025 1082
1083 IPC::ChannelHandle handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
1084 handle.socket = base::FileDescriptor(fd1, true);
1085 channel_handle1->reset(handle);
1086 handle.socket = base::FileDescriptor(fd2, true);
1087 channel_handle2->reset(handle);
1088 return true;
1089 }
1090 #endif
1091
1092 bool NaClProcessHost::StartPPAPIProxy(ScopedChannelHandle channel_handle) {
1026 if (ipc_proxy_channel_.get()) { 1093 if (ipc_proxy_channel_.get()) {
1027 // Attempt to open more than 1 browser channel is not supported. 1094 // Attempt to open more than 1 browser channel is not supported.
1028 // Shut down the NaCl process. 1095 // Shut down the NaCl process.
1029 process_->GetHost()->ForceShutdown(); 1096 process_->GetHost()->ForceShutdown();
1030 return; 1097 return false;
1031 } 1098 }
1032 1099
1033 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); 1100 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type);
1034 1101
1035 ipc_proxy_channel_ = 1102 ipc_proxy_channel_ = IPC::ChannelProxy::Create(
1036 IPC::ChannelProxy::Create(browser_channel_handle.release(), 1103 channel_handle.release(),
1037 IPC::Channel::MODE_CLIENT, 1104 IPC::Channel::MODE_CLIENT,
1038 NULL, 1105 NULL,
1039 base::MessageLoopProxy::current().get()); 1106 base::MessageLoopProxy::current().get());
1040 // Create the browser ppapi host and enable PPAPI message dispatching to the 1107 // Create the browser ppapi host and enable PPAPI message dispatching to the
1041 // browser process. 1108 // browser process.
1042 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( 1109 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess(
1043 ipc_proxy_channel_.get(), // sender 1110 ipc_proxy_channel_.get(), // sender
1044 permissions_, 1111 permissions_,
1045 process_->GetData().handle, 1112 process_->GetData().handle,
1046 ipc_proxy_channel_.get(), 1113 ipc_proxy_channel_.get(),
1047 nacl_host_message_filter_->render_process_id(), 1114 nacl_host_message_filter_->render_process_id(),
1048 render_view_id_, 1115 render_view_id_,
1049 profile_directory_)); 1116 profile_directory_));
(...skipping 19 matching lines...) Expand all
1069 } 1136 }
1070 } 1137 }
1071 1138
1072 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( 1139 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter(
1073 scoped_ptr<ppapi::host::HostFactory>( 1140 scoped_ptr<ppapi::host::HostFactory>(
1074 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( 1141 NaClBrowser::GetDelegate()->CreatePpapiHostFactory(
1075 ppapi_host_.get()))); 1142 ppapi_host_.get())));
1076 1143
1077 // Send a message to initialize the IPC dispatchers in the NaCl plugin. 1144 // Send a message to initialize the IPC dispatchers in the NaCl plugin.
1078 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); 1145 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args));
1146 return true;
1147 }
1148
1149 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is
1150 // received.
1151 void NaClProcessHost::OnPpapiChannelsCreated(
1152 const IPC::ChannelHandle& raw_ppapi_browser_channel_handle,
1153 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle,
1154 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle,
1155 const IPC::ChannelHandle& raw_manifest_service_channel_handle) {
1156 ScopedChannelHandle ppapi_browser_channel_handle(
1157 raw_ppapi_browser_channel_handle);
1158 ScopedChannelHandle ppapi_renderer_channel_handle(
1159 raw_ppapi_renderer_channel_handle);
1160 ScopedChannelHandle trusted_renderer_channel_handle(
1161 raw_trusted_renderer_channel_handle);
1162 ScopedChannelHandle manifest_service_channel_handle(
1163 raw_manifest_service_channel_handle);
1164
1165 if (enable_ppapi_proxy()) {
1166 if (!StartPPAPIProxy(ppapi_browser_channel_handle.Pass())) {
1167 SendErrorToRenderer("Browser PPAPI proxy could not start.");
1168 return;
1169 }
1170 } else {
1171 // If PPAPI proxy is disabled, channel handles should be invalid.
1172 DCHECK(ppapi_browser_channel_handle.get().name.empty());
1173 DCHECK(ppapi_renderer_channel_handle.get().name.empty());
1174 // Invalidate, just in case.
1175 ppapi_browser_channel_handle.reset();
1176 ppapi_renderer_channel_handle.reset();
1177 }
1079 1178
1080 // Let the renderer know that the IPC channels are established. 1179 // Let the renderer know that the IPC channels are established.
1081 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(), 1180 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(),
1082 trusted_renderer_channel_handle.Pass(), 1181 trusted_renderer_channel_handle.Pass(),
1083 manifest_service_channel_handle.Pass()); 1182 manifest_service_channel_handle.Pass());
1084 } 1183 }
1085 1184
1086 bool NaClProcessHost::StartWithLaunchedProcess() { 1185 bool NaClProcessHost::StartWithLaunchedProcess() {
1087 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 1186 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
1088 1187
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 process.Pass(), info, 1353 process.Pass(), info,
1255 base::MessageLoopProxy::current(), 1354 base::MessageLoopProxy::current(),
1256 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 1355 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
1257 weak_factory_.GetWeakPtr())); 1356 weak_factory_.GetWeakPtr()));
1258 return true; 1357 return true;
1259 } 1358 }
1260 } 1359 }
1261 #endif 1360 #endif
1262 1361
1263 } // namespace nacl 1362 } // namespace nacl
OLDNEW
« no previous file with comments | « components/nacl/browser/nacl_process_host.h ('k') | components/nacl/common/nacl_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698