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

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: Rebase & reimplement 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 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 } 665 }
666 #endif 666 #endif
667 process_->Launch( 667 process_->Launch(
668 new NaClSandboxedProcessLauncherDelegate(process_->GetHost()), 668 new NaClSandboxedProcessLauncherDelegate(process_->GetHost()),
669 cmd_line.release(), 669 cmd_line.release(),
670 true); 670 true);
671 return true; 671 return true;
672 } 672 }
673 673
674 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { 674 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
675 if (uses_nonsfi_mode_) {
676 // In Non-SFI mode, no message is expected.
677 return false;
678 }
679
675 bool handled = true; 680 bool handled = true;
676 if (uses_nonsfi_mode_) { 681 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg)
677 // IPC messages relating to NaCl's validation cache must not be exposed 682 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate,
Mark Seaborn 2015/05/12 23:24:06 Please keep this comment, and add it after "// In
hidehiko 2015/05/13 06:39:20 Done.
678 // in Non-SFI Mode, otherwise a Non-SFI nexe could use 683 OnQueryKnownToValidate)
679 // SetKnownToValidate to create a hole in the SFI sandbox. 684 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate,
680 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) 685 OnSetKnownToValidate)
681 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, 686 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileToken,
682 OnPpapiChannelsCreated) 687 OnResolveFileToken)
683 IPC_MESSAGE_UNHANDLED(handled = false)
684 IPC_END_MESSAGE_MAP()
685 } else {
686 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg)
687 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate,
688 OnQueryKnownToValidate)
689 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate,
690 OnSetKnownToValidate)
691 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileToken,
692 OnResolveFileToken)
693 688
694 #if defined(OS_WIN) 689 #if defined(OS_WIN)
695 IPC_MESSAGE_HANDLER_DELAY_REPLY( 690 IPC_MESSAGE_HANDLER_DELAY_REPLY(
696 NaClProcessMsg_AttachDebugExceptionHandler, 691 NaClProcessMsg_AttachDebugExceptionHandler,
697 OnAttachDebugExceptionHandler) 692 OnAttachDebugExceptionHandler)
698 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected, 693 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected,
699 OnDebugStubPortSelected) 694 OnDebugStubPortSelected)
700 #endif 695 #endif
701 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, 696 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated,
702 OnPpapiChannelsCreated) 697 OnPpapiChannelsCreated)
703 IPC_MESSAGE_UNHANDLED(handled = false) 698 IPC_MESSAGE_UNHANDLED(handled = false)
704 IPC_END_MESSAGE_MAP() 699 IPC_END_MESSAGE_MAP()
705 }
706 return handled; 700 return handled;
707 } 701 }
708 702
709 void NaClProcessHost::OnProcessLaunched() { 703 void NaClProcessHost::OnProcessLaunched() {
710 if (!StartWithLaunchedProcess()) 704 if (!StartWithLaunchedProcess())
711 delete this; 705 delete this;
712 } 706 }
713 707
714 // Called when the NaClBrowser singleton has been fully initialized. 708 // Called when the NaClBrowser singleton has been fully initialized.
715 void NaClProcessHost::OnResourcesReady() { 709 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. 859 // Currently, non-SFI mode is supported only on Linux.
866 #if defined(OS_LINUX) 860 #if defined(OS_LINUX)
867 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is 861 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is
868 // not created. 862 // not created.
869 DCHECK(!socket_for_sel_ldr_.IsValid()); 863 DCHECK(!socket_for_sel_ldr_.IsValid());
870 #endif 864 #endif
871 if (enable_nacl_debug) { 865 if (enable_nacl_debug) {
872 base::ProcessId pid = base::GetProcId(process_->GetData().handle); 866 base::ProcessId pid = base::GetProcId(process_->GetData().handle);
873 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; 867 LOG(WARNING) << "nonsfi nacl plugin running in " << pid;
874 } 868 }
869
870 DCHECK(params.enable_ipc_proxy);
871 if (!params.enable_ipc_proxy) {
Mark Seaborn 2015/05/12 23:24:06 This is basically input validation of what the ren
hidehiko 2015/05/13 06:39:20 Done.
872 LOG(ERROR) << "In Non-SFI mode, PPAPI proxy must be enabled.";
873 return false;
874 }
875 } else { 875 } else {
876 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); 876 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled();
877 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); 877 params.validation_cache_key = nacl_browser->GetValidationCacheKey();
878 params.version = NaClBrowser::GetDelegate()->GetVersionString(); 878 params.version = NaClBrowser::GetDelegate()->GetVersionString();
879 params.enable_debug_stub = enable_nacl_debug; 879 params.enable_debug_stub = enable_nacl_debug;
880 880
881 const ChildProcessData& data = process_->GetData(); 881 const ChildProcessData& data = process_->GetData();
882 params.imc_bootstrap_handle = 882 params.imc_bootstrap_handle =
883 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), data.handle); 883 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), data.handle);
884 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) { 884 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 true /* is_executable */), 968 true /* is_executable */),
969 base::Bind(&NaClProcessHost::StartNaClFileResolved, 969 base::Bind(&NaClProcessHost::StartNaClFileResolved,
970 weak_factory_.GetWeakPtr(), 970 weak_factory_.GetWeakPtr(),
971 params, 971 params,
972 file_path))) { 972 file_path))) {
973 return true; 973 return true;
974 } 974 }
975 } 975 }
976 } 976 }
977 977
978 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), 978 StartNaClFileResolved(params, base::FilePath(), base::File());
979 process_->GetData().handle);
980 process_->Send(new NaClProcessMsg_Start(params));
981 return true; 979 return true;
982 } 980 }
983 981
984 void NaClProcessHost::StartNaClFileResolved( 982 void NaClProcessHost::StartNaClFileResolved(
985 NaClStartParams params, 983 NaClStartParams params,
986 const base::FilePath& file_path, 984 const base::FilePath& file_path,
987 base::File checked_nexe_file) { 985 base::File checked_nexe_file) {
988 if (checked_nexe_file.IsValid()) { 986 if (checked_nexe_file.IsValid()) {
989 // Release the file received from the renderer. This has to be done on a 987 // Release the file received from the renderer. This has to be done on a
990 // thread where IO is permitted, though. 988 // thread where IO is permitted, though.
991 content::BrowserThread::GetBlockingPool()->PostTask( 989 content::BrowserThread::GetBlockingPool()->PostTask(
992 FROM_HERE, 990 FROM_HERE,
993 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); 991 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass())));
994 params.nexe_file_path_metadata = file_path; 992 params.nexe_file_path_metadata = file_path;
995 params.nexe_file = IPC::TakeFileHandleForProcess( 993 params.nexe_file = IPC::TakeFileHandleForProcess(
996 checked_nexe_file.Pass(), process_->GetData().handle); 994 checked_nexe_file.Pass(), process_->GetData().handle);
997 } else { 995 } else {
998 params.nexe_file = IPC::TakeFileHandleForProcess( 996 params.nexe_file = IPC::TakeFileHandleForProcess(
999 nexe_file_.Pass(), process_->GetData().handle); 997 nexe_file_.Pass(), process_->GetData().handle);
1000 } 998 }
999
1000 #if defined(OS_LINUX)
1001 // In Non-SFI mode, create socket pairs for IPC channels, here, unlike in
Mark Seaborn 2015/05/12 23:24:06 Grammar nit: could remove comma before "here"
hidehiko 2015/05/13 06:39:20 Done.
1002 // SFI-mode, in which those channels are created in nacl_listener.cc.
1003 // This is for security hardening. We can then prohibit the socketpair()
1004 // system call in nacl_helper and nacl_helper_nonsfi.
1005 if (uses_nonsfi_mode_) {
1006 // Note: here, because some resources for the plugin process are already
Mark Seaborn 2015/05/12 23:24:06 Nit: "plugin process" -> "NaCl loader process", x2
hidehiko 2015/05/13 06:39:20 Done.
1007 // opened, they must be sent to plugin process because these cannot be
Mark Seaborn 2015/05/12 23:24:06 "cannot be closed in this process" could be mislea
hidehiko 2015/05/13 06:39:20 Done.
1008 // closed in this process properly.
1009 bool has_error = false;
1010
1011 // The case this condition is not satisfied should be handled in
Mark Seaborn 2015/05/12 23:24:06 Nit: "The case where this condition..." perhaps?
hidehiko 2015/05/13 06:39:20 Done.
1012 // StartNaClExecution().
1013 DCHECK(params.enable_ipc_proxy);
1014
1015 ScopedChannelHandle ppapi_browser_server_channel_handle;
Mark Seaborn 2015/05/12 23:24:06 I wonder if it would it be worth doing: typedef s
hidehiko 2015/05/13 06:39:20 I do not want to introduce such a pair. Indeed it
1016 ScopedChannelHandle ppapi_browser_client_channel_handle;
1017 ScopedChannelHandle ppapi_renderer_server_channel_handle;
1018 ScopedChannelHandle ppapi_renderer_client_channel_handle;
1019 ScopedChannelHandle trusted_service_server_channel_handle;
1020 ScopedChannelHandle trusted_service_client_channel_handle;
1021 ScopedChannelHandle manifest_service_server_channel_handle;
1022 ScopedChannelHandle manifest_service_client_channel_handle;
1023
1024 if (!CreateChannelHandlePair(&ppapi_browser_server_channel_handle,
1025 &ppapi_browser_client_channel_handle) ||
1026 !CreateChannelHandlePair(&ppapi_renderer_server_channel_handle,
1027 &ppapi_renderer_client_channel_handle) ||
1028 !CreateChannelHandlePair(&trusted_service_server_channel_handle,
1029 &trusted_service_client_channel_handle) ||
1030 !CreateChannelHandlePair(&manifest_service_server_channel_handle,
1031 &manifest_service_client_channel_handle)) {
1032 SendErrorToRenderer("Failed to create socket pairs.");
1033 has_error = true;
1034 }
1035
1036 if (!has_error &&
1037 !StartPPAPIProxy(ppapi_browser_client_channel_handle.Pass())) {
1038 SendErrorToRenderer("Failed to start browser PPAPI proxy.");
1039 has_error = true;
1040 }
1041
1042 if (!has_error) {
1043 // On success, send back a success message to the renderer process,
1044 // and, transfer the channel handles for the plugin process to |params|.
Mark Seaborn 2015/05/12 23:24:06 Nit: remove comma after "and" Also "plugin proces
hidehiko 2015/05/13 06:39:20 Done.
1045 ReplyToRenderer(ppapi_renderer_client_channel_handle.Pass(),
1046 trusted_service_client_channel_handle.Pass(),
1047 manifest_service_client_channel_handle.Pass());
1048 params.ppapi_browser_channel_handle =
1049 ppapi_browser_server_channel_handle.release();
1050 params.ppapi_renderer_channel_handle =
1051 ppapi_renderer_server_channel_handle.release();
1052 params.trusted_service_channel_handle =
1053 trusted_service_server_channel_handle.release();
1054 params.manifest_service_channel_handle =
1055 manifest_service_server_channel_handle.release();
1056 }
1057 }
1058 #endif
1059
1001 process_->Send(new NaClProcessMsg_Start(params)); 1060 process_->Send(new NaClProcessMsg_Start(params));
1002 } 1061 }
1003 1062
1004 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is 1063 #if defined(OS_LINUX)
1005 // received. 1064 // static
1006 void NaClProcessHost::OnPpapiChannelsCreated( 1065 bool NaClProcessHost::CreateChannelHandlePair(
1007 const IPC::ChannelHandle& raw_browser_channel_handle, 1066 ScopedChannelHandle* channel_handle1,
1008 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle, 1067 ScopedChannelHandle* channel_handle2) {
1009 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle, 1068 DCHECK(channel_handle1);
1010 const IPC::ChannelHandle& raw_manifest_service_channel_handle) { 1069 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 1070
1019 if (!enable_ppapi_proxy()) { 1071 int fd1 = -1;
1020 ReplyToRenderer(ScopedChannelHandle(), 1072 int fd2 = -1;
1021 trusted_renderer_channel_handle.Pass(), 1073 if (!IPC::SocketPair(&fd1, &fd2)) {
1022 manifest_service_channel_handle.Pass()); 1074 return false;
1023 return;
1024 } 1075 }
1025 1076
1077 IPC::ChannelHandle handle = IPC::Channel::GenerateVerifiedChannelID("nacl");
1078 handle.socket = base::FileDescriptor(fd1, true);
1079 channel_handle1->reset(handle);
1080 handle.socket = base::FileDescriptor(fd2, true);
1081 channel_handle2->reset(handle);
1082 return true;
1083 }
1084 #endif
1085
1086 bool NaClProcessHost::StartPPAPIProxy(ScopedChannelHandle channel_handle) {
1026 if (ipc_proxy_channel_.get()) { 1087 if (ipc_proxy_channel_.get()) {
1027 // Attempt to open more than 1 browser channel is not supported. 1088 // Attempt to open more than 1 browser channel is not supported.
1028 // Shut down the NaCl process. 1089 // Shut down the NaCl process.
1029 process_->GetHost()->ForceShutdown(); 1090 process_->GetHost()->ForceShutdown();
1030 return; 1091 return false;
1031 } 1092 }
1032 1093
1033 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); 1094 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type);
1034 1095
1035 ipc_proxy_channel_ = 1096 ipc_proxy_channel_ = IPC::ChannelProxy::Create(
1036 IPC::ChannelProxy::Create(browser_channel_handle.release(), 1097 channel_handle.release(),
1037 IPC::Channel::MODE_CLIENT, 1098 IPC::Channel::MODE_CLIENT,
1038 NULL, 1099 NULL,
1039 base::MessageLoopProxy::current().get()); 1100 base::MessageLoopProxy::current().get());
1040 // Create the browser ppapi host and enable PPAPI message dispatching to the 1101 // Create the browser ppapi host and enable PPAPI message dispatching to the
1041 // browser process. 1102 // browser process.
1042 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( 1103 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess(
1043 ipc_proxy_channel_.get(), // sender 1104 ipc_proxy_channel_.get(), // sender
1044 permissions_, 1105 permissions_,
1045 process_->GetData().handle, 1106 process_->GetData().handle,
1046 ipc_proxy_channel_.get(), 1107 ipc_proxy_channel_.get(),
1047 nacl_host_message_filter_->render_process_id(), 1108 nacl_host_message_filter_->render_process_id(),
1048 render_view_id_, 1109 render_view_id_,
1049 profile_directory_)); 1110 profile_directory_));
(...skipping 19 matching lines...) Expand all
1069 } 1130 }
1070 } 1131 }
1071 1132
1072 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( 1133 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter(
1073 scoped_ptr<ppapi::host::HostFactory>( 1134 scoped_ptr<ppapi::host::HostFactory>(
1074 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( 1135 NaClBrowser::GetDelegate()->CreatePpapiHostFactory(
1075 ppapi_host_.get()))); 1136 ppapi_host_.get())));
1076 1137
1077 // Send a message to initialize the IPC dispatchers in the NaCl plugin. 1138 // Send a message to initialize the IPC dispatchers in the NaCl plugin.
1078 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); 1139 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args));
1140 return true;
1141 }
1142
1143 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is
1144 // received.
1145 void NaClProcessHost::OnPpapiChannelsCreated(
1146 const IPC::ChannelHandle& raw_ppapi_browser_channel_handle,
1147 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle,
1148 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle,
1149 const IPC::ChannelHandle& raw_manifest_service_channel_handle) {
1150 ScopedChannelHandle ppapi_browser_channel_handle(
1151 raw_ppapi_browser_channel_handle);
1152 ScopedChannelHandle ppapi_renderer_channel_handle(
1153 raw_ppapi_renderer_channel_handle);
1154 ScopedChannelHandle trusted_renderer_channel_handle(
1155 raw_trusted_renderer_channel_handle);
1156 ScopedChannelHandle manifest_service_channel_handle(
1157 raw_manifest_service_channel_handle);
1158
1159 if (enable_ppapi_proxy()) {
1160 if (!StartPPAPIProxy(ppapi_browser_channel_handle.Pass())) {
1161 SendErrorToRenderer("Browser PPAPI proxy could not start.");
1162 return;
1163 }
1164 } else {
1165 // If PPAPI proxy is disabled, channel handles should be invalid.
1166 DCHECK(ppapi_browser_channel_handle.get().name.empty());
1167 DCHECK(ppapi_renderer_channel_handle.get().name.empty());
1168 // Invalidate, just in case.
1169 ppapi_browser_channel_handle.reset();
1170 ppapi_renderer_channel_handle.reset();
1171 }
1079 1172
1080 // Let the renderer know that the IPC channels are established. 1173 // Let the renderer know that the IPC channels are established.
1081 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(), 1174 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(),
1082 trusted_renderer_channel_handle.Pass(), 1175 trusted_renderer_channel_handle.Pass(),
1083 manifest_service_channel_handle.Pass()); 1176 manifest_service_channel_handle.Pass());
1084 } 1177 }
1085 1178
1086 bool NaClProcessHost::StartWithLaunchedProcess() { 1179 bool NaClProcessHost::StartWithLaunchedProcess() {
1087 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 1180 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
1088 1181
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 process.Pass(), info, 1347 process.Pass(), info,
1255 base::MessageLoopProxy::current(), 1348 base::MessageLoopProxy::current(),
1256 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 1349 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
1257 weak_factory_.GetWeakPtr())); 1350 weak_factory_.GetWeakPtr()));
1258 return true; 1351 return true;
1259 } 1352 }
1260 } 1353 }
1261 #endif 1354 #endif
1262 1355
1263 } // namespace nacl 1356 } // namespace nacl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698