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

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
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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 // Currently, non-SFI mode is supported only on Linux. 869 // Currently, non-SFI mode is supported only on Linux.
866 #if defined(OS_LINUX) 870 #if defined(OS_LINUX)
867 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is 871 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is
868 // not created. 872 // not created.
869 DCHECK(!socket_for_sel_ldr_.IsValid()); 873 DCHECK(!socket_for_sel_ldr_.IsValid());
870 #endif 874 #endif
871 if (enable_nacl_debug) { 875 if (enable_nacl_debug) {
872 base::ProcessId pid = base::GetProcId(process_->GetData().handle); 876 base::ProcessId pid = base::GetProcId(process_->GetData().handle);
873 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; 877 LOG(WARNING) << "nonsfi nacl plugin running in " << pid;
874 } 878 }
879 DCHECK(params.enable_ipc_proxy);
Mark Seaborn 2015/05/13 06:51:11 Nit: This isn't needed now, since you check this b
hidehiko 2015/05/13 14:44:48 Done.
875 } else { 880 } else {
876 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); 881 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled();
877 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); 882 params.validation_cache_key = nacl_browser->GetValidationCacheKey();
878 params.version = NaClBrowser::GetDelegate()->GetVersionString(); 883 params.version = NaClBrowser::GetDelegate()->GetVersionString();
879 params.enable_debug_stub = enable_nacl_debug; 884 params.enable_debug_stub = enable_nacl_debug;
880 885
881 const ChildProcessData& data = process_->GetData(); 886 const ChildProcessData& data = process_->GetData();
882 params.imc_bootstrap_handle = 887 params.imc_bootstrap_handle =
883 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), data.handle); 888 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), data.handle);
884 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) { 889 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 true /* is_executable */), 973 true /* is_executable */),
969 base::Bind(&NaClProcessHost::StartNaClFileResolved, 974 base::Bind(&NaClProcessHost::StartNaClFileResolved,
970 weak_factory_.GetWeakPtr(), 975 weak_factory_.GetWeakPtr(),
971 params, 976 params,
972 file_path))) { 977 file_path))) {
973 return true; 978 return true;
974 } 979 }
975 } 980 }
976 } 981 }
977 982
978 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), 983 StartNaClFileResolved(params, base::FilePath(), base::File());
979 process_->GetData().handle);
980 process_->Send(new NaClProcessMsg_Start(params));
981 return true; 984 return true;
982 } 985 }
983 986
984 void NaClProcessHost::StartNaClFileResolved( 987 void NaClProcessHost::StartNaClFileResolved(
985 NaClStartParams params, 988 NaClStartParams params,
986 const base::FilePath& file_path, 989 const base::FilePath& file_path,
987 base::File checked_nexe_file) { 990 base::File checked_nexe_file) {
988 if (checked_nexe_file.IsValid()) { 991 if (checked_nexe_file.IsValid()) {
989 // Release the file received from the renderer. This has to be done on a 992 // Release the file received from the renderer. This has to be done on a
990 // thread where IO is permitted, though. 993 // thread where IO is permitted, though.
991 content::BrowserThread::GetBlockingPool()->PostTask( 994 content::BrowserThread::GetBlockingPool()->PostTask(
992 FROM_HERE, 995 FROM_HERE,
993 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); 996 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass())));
994 params.nexe_file_path_metadata = file_path; 997 params.nexe_file_path_metadata = file_path;
995 params.nexe_file = IPC::TakeFileHandleForProcess( 998 params.nexe_file = IPC::TakeFileHandleForProcess(
996 checked_nexe_file.Pass(), process_->GetData().handle); 999 checked_nexe_file.Pass(), process_->GetData().handle);
997 } else { 1000 } else {
998 params.nexe_file = IPC::TakeFileHandleForProcess( 1001 params.nexe_file = IPC::TakeFileHandleForProcess(
999 nexe_file_.Pass(), process_->GetData().handle); 1002 nexe_file_.Pass(), process_->GetData().handle);
1000 } 1003 }
1004
1005 #if defined(OS_LINUX)
1006 // In Non-SFI mode, create socket pairs for IPC channels here, unlike in
1007 // SFI-mode, in which those channels are created in nacl_listener.cc.
1008 // This is for security hardening. We can then prohibit the socketpair()
1009 // system call in nacl_helper and nacl_helper_nonsfi.
1010 if (uses_nonsfi_mode_) {
1011 // Note: here, because some FDs/handles for the NaCl loader process are
1012 // already opened, they are transferred to NaCl loader process even if
1013 // an error occurs first. It is because this is the simplest way to
1014 // ensure that these FDs/handles don't get leaked and that the NaCl loader
1015 // process will exit properly.
1016 bool has_error = false;
1017
1018 // Note: this check is redundant. We check this earlier.
1019 DCHECK(params.enable_ipc_proxy);
1020
1021 ScopedChannelHandle ppapi_browser_server_channel_handle;
1022 ScopedChannelHandle ppapi_browser_client_channel_handle;
1023 ScopedChannelHandle ppapi_renderer_server_channel_handle;
1024 ScopedChannelHandle ppapi_renderer_client_channel_handle;
1025 ScopedChannelHandle trusted_service_server_channel_handle;
1026 ScopedChannelHandle trusted_service_client_channel_handle;
1027 ScopedChannelHandle manifest_service_server_channel_handle;
1028 ScopedChannelHandle manifest_service_client_channel_handle;
1029
1030 if (!CreateChannelHandlePair(&ppapi_browser_server_channel_handle,
1031 &ppapi_browser_client_channel_handle) ||
1032 !CreateChannelHandlePair(&ppapi_renderer_server_channel_handle,
1033 &ppapi_renderer_client_channel_handle) ||
1034 !CreateChannelHandlePair(&trusted_service_server_channel_handle,
1035 &trusted_service_client_channel_handle) ||
1036 !CreateChannelHandlePair(&manifest_service_server_channel_handle,
1037 &manifest_service_client_channel_handle)) {
1038 SendErrorToRenderer("Failed to create socket pairs.");
1039 has_error = true;
1040 }
1041
1042 if (!has_error &&
1043 !StartPPAPIProxy(ppapi_browser_client_channel_handle.Pass())) {
1044 SendErrorToRenderer("Failed to start browser PPAPI proxy.");
1045 has_error = true;
1046 }
1047
1048 if (!has_error) {
1049 // On success, send back a success message to the renderer process,
1050 // and transfer the channel handles for the NaCl loader process to
1051 // |params|.
1052 ReplyToRenderer(ppapi_renderer_client_channel_handle.Pass(),
1053 trusted_service_client_channel_handle.Pass(),
1054 manifest_service_client_channel_handle.Pass());
1055 params.ppapi_browser_channel_handle =
1056 ppapi_browser_server_channel_handle.release();
1057 params.ppapi_renderer_channel_handle =
1058 ppapi_renderer_server_channel_handle.release();
1059 params.trusted_service_channel_handle =
1060 trusted_service_server_channel_handle.release();
1061 params.manifest_service_channel_handle =
1062 manifest_service_server_channel_handle.release();
1063 }
1064 }
1065 #endif
1066
1001 process_->Send(new NaClProcessMsg_Start(params)); 1067 process_->Send(new NaClProcessMsg_Start(params));
1002 } 1068 }
1003 1069
1004 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is 1070 #if defined(OS_LINUX)
1005 // received. 1071 // static
1006 void NaClProcessHost::OnPpapiChannelsCreated( 1072 bool NaClProcessHost::CreateChannelHandlePair(
1007 const IPC::ChannelHandle& raw_browser_channel_handle, 1073 ScopedChannelHandle* channel_handle1,
1008 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle, 1074 ScopedChannelHandle* channel_handle2) {
1009 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle, 1075 DCHECK(channel_handle1);
1010 const IPC::ChannelHandle& raw_manifest_service_channel_handle) { 1076 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 1077
1019 if (!enable_ppapi_proxy()) { 1078 int fd1 = -1;
1020 ReplyToRenderer(ScopedChannelHandle(), 1079 int fd2 = -1;
1021 trusted_renderer_channel_handle.Pass(), 1080 if (!IPC::SocketPair(&fd1, &fd2)) {
1022 manifest_service_channel_handle.Pass()); 1081 return false;
1023 return;
1024 } 1082 }
1025 1083
1084 IPC::ChannelHandle handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
1085 handle.socket = base::FileDescriptor(fd1, true);
1086 channel_handle1->reset(handle);
1087 handle.socket = base::FileDescriptor(fd2, true);
1088 channel_handle2->reset(handle);
1089 return true;
1090 }
1091 #endif
1092
1093 bool NaClProcessHost::StartPPAPIProxy(ScopedChannelHandle channel_handle) {
1026 if (ipc_proxy_channel_.get()) { 1094 if (ipc_proxy_channel_.get()) {
1027 // Attempt to open more than 1 browser channel is not supported. 1095 // Attempt to open more than 1 browser channel is not supported.
1028 // Shut down the NaCl process. 1096 // Shut down the NaCl process.
1029 process_->GetHost()->ForceShutdown(); 1097 process_->GetHost()->ForceShutdown();
1030 return; 1098 return false;
1031 } 1099 }
1032 1100
1033 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); 1101 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type);
1034 1102
1035 ipc_proxy_channel_ = 1103 ipc_proxy_channel_ = IPC::ChannelProxy::Create(
1036 IPC::ChannelProxy::Create(browser_channel_handle.release(), 1104 channel_handle.release(),
1037 IPC::Channel::MODE_CLIENT, 1105 IPC::Channel::MODE_CLIENT,
1038 NULL, 1106 NULL,
1039 base::MessageLoopProxy::current().get()); 1107 base::MessageLoopProxy::current().get());
1040 // Create the browser ppapi host and enable PPAPI message dispatching to the 1108 // Create the browser ppapi host and enable PPAPI message dispatching to the
1041 // browser process. 1109 // browser process.
1042 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( 1110 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess(
1043 ipc_proxy_channel_.get(), // sender 1111 ipc_proxy_channel_.get(), // sender
1044 permissions_, 1112 permissions_,
1045 process_->GetData().handle, 1113 process_->GetData().handle,
1046 ipc_proxy_channel_.get(), 1114 ipc_proxy_channel_.get(),
1047 nacl_host_message_filter_->render_process_id(), 1115 nacl_host_message_filter_->render_process_id(),
1048 render_view_id_, 1116 render_view_id_,
1049 profile_directory_)); 1117 profile_directory_));
(...skipping 19 matching lines...) Expand all
1069 } 1137 }
1070 } 1138 }
1071 1139
1072 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( 1140 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter(
1073 scoped_ptr<ppapi::host::HostFactory>( 1141 scoped_ptr<ppapi::host::HostFactory>(
1074 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( 1142 NaClBrowser::GetDelegate()->CreatePpapiHostFactory(
1075 ppapi_host_.get()))); 1143 ppapi_host_.get())));
1076 1144
1077 // Send a message to initialize the IPC dispatchers in the NaCl plugin. 1145 // Send a message to initialize the IPC dispatchers in the NaCl plugin.
1078 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); 1146 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args));
1147 return true;
1148 }
1149
1150 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is
1151 // received.
1152 void NaClProcessHost::OnPpapiChannelsCreated(
1153 const IPC::ChannelHandle& raw_ppapi_browser_channel_handle,
1154 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle,
1155 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle,
1156 const IPC::ChannelHandle& raw_manifest_service_channel_handle) {
1157 ScopedChannelHandle ppapi_browser_channel_handle(
1158 raw_ppapi_browser_channel_handle);
1159 ScopedChannelHandle ppapi_renderer_channel_handle(
1160 raw_ppapi_renderer_channel_handle);
1161 ScopedChannelHandle trusted_renderer_channel_handle(
1162 raw_trusted_renderer_channel_handle);
1163 ScopedChannelHandle manifest_service_channel_handle(
1164 raw_manifest_service_channel_handle);
1165
1166 if (enable_ppapi_proxy()) {
1167 if (!StartPPAPIProxy(ppapi_browser_channel_handle.Pass())) {
1168 SendErrorToRenderer("Browser PPAPI proxy could not start.");
1169 return;
1170 }
1171 } else {
1172 // If PPAPI proxy is disabled, channel handles should be invalid.
1173 DCHECK(ppapi_browser_channel_handle.get().name.empty());
1174 DCHECK(ppapi_renderer_channel_handle.get().name.empty());
1175 // Invalidate, just in case.
1176 ppapi_browser_channel_handle.reset();
1177 ppapi_renderer_channel_handle.reset();
1178 }
1079 1179
1080 // Let the renderer know that the IPC channels are established. 1180 // Let the renderer know that the IPC channels are established.
1081 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(), 1181 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(),
1082 trusted_renderer_channel_handle.Pass(), 1182 trusted_renderer_channel_handle.Pass(),
1083 manifest_service_channel_handle.Pass()); 1183 manifest_service_channel_handle.Pass());
1084 } 1184 }
1085 1185
1086 bool NaClProcessHost::StartWithLaunchedProcess() { 1186 bool NaClProcessHost::StartWithLaunchedProcess() {
1087 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 1187 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
1088 1188
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 process.Pass(), info, 1354 process.Pass(), info,
1255 base::MessageLoopProxy::current(), 1355 base::MessageLoopProxy::current(),
1256 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 1356 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
1257 weak_factory_.GetWeakPtr())); 1357 weak_factory_.GetWeakPtr()));
1258 return true; 1358 return true;
1259 } 1359 }
1260 } 1360 }
1261 #endif 1361 #endif
1262 1362
1263 } // namespace nacl 1363 } // namespace nacl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698