OLD | NEW |
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 | |
9 #include <algorithm> | 8 #include <algorithm> |
10 #include <string> | 9 #include <string> |
| 10 #include <utility> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/base_switches.h" | 13 #include "base/base_switches.h" |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
16 #include "base/files/file_util.h" | 16 #include "base/files/file_util.h" |
17 #include "base/location.h" | 17 #include "base/location.h" |
18 #include "base/macros.h" | 18 #include "base/macros.h" |
19 #include "base/metrics/histogram_macros.h" | 19 #include "base/metrics/histogram_macros.h" |
20 #include "base/path_service.h" | 20 #include "base/path_service.h" |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 const NaClFileToken& nexe_token, | 282 const NaClFileToken& nexe_token, |
283 const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, | 283 const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, |
284 ppapi::PpapiPermissions permissions, | 284 ppapi::PpapiPermissions permissions, |
285 int render_view_id, | 285 int render_view_id, |
286 uint32_t permission_bits, | 286 uint32_t permission_bits, |
287 bool uses_nonsfi_mode, | 287 bool uses_nonsfi_mode, |
288 bool off_the_record, | 288 bool off_the_record, |
289 NaClAppProcessType process_type, | 289 NaClAppProcessType process_type, |
290 const base::FilePath& profile_directory) | 290 const base::FilePath& profile_directory) |
291 : manifest_url_(manifest_url), | 291 : manifest_url_(manifest_url), |
292 nexe_file_(nexe_file.Pass()), | 292 nexe_file_(std::move(nexe_file)), |
293 nexe_token_(nexe_token), | 293 nexe_token_(nexe_token), |
294 prefetched_resource_files_(prefetched_resource_files), | 294 prefetched_resource_files_(prefetched_resource_files), |
295 permissions_(permissions), | 295 permissions_(permissions), |
296 #if defined(OS_WIN) | 296 #if defined(OS_WIN) |
297 process_launched_by_broker_(false), | 297 process_launched_by_broker_(false), |
298 #endif | 298 #endif |
299 reply_msg_(NULL), | 299 reply_msg_(NULL), |
300 #if defined(OS_WIN) | 300 #if defined(OS_WIN) |
301 debug_exception_handler_requested_(false), | 301 debug_exception_handler_requested_(false), |
302 #endif | 302 #endif |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 // prefetching feature only on POSIX platforms, so it should be ok. | 343 // prefetching feature only on POSIX platforms, so it should be ok. |
344 #if defined(OS_WIN) | 344 #if defined(OS_WIN) |
345 DCHECK(prefetched_resource_files_.empty()); | 345 DCHECK(prefetched_resource_files_.empty()); |
346 #else | 346 #else |
347 for (size_t i = 0; i < prefetched_resource_files_.size(); ++i) { | 347 for (size_t i = 0; i < prefetched_resource_files_.size(); ++i) { |
348 // The process failed to launch for some reason. Close resource file | 348 // The process failed to launch for some reason. Close resource file |
349 // handles. | 349 // handles. |
350 base::File file(IPC::PlatformFileForTransitToFile( | 350 base::File file(IPC::PlatformFileForTransitToFile( |
351 prefetched_resource_files_[i].file)); | 351 prefetched_resource_files_[i].file)); |
352 content::BrowserThread::GetBlockingPool()->PostTask( | 352 content::BrowserThread::GetBlockingPool()->PostTask( |
353 FROM_HERE, | 353 FROM_HERE, base::Bind(&CloseFile, base::Passed(std::move(file)))); |
354 base::Bind(&CloseFile, base::Passed(file.Pass()))); | |
355 } | 354 } |
356 #endif | 355 #endif |
357 base::File files_to_close[] = { | 356 base::File files_to_close[] = { |
358 nexe_file_.Pass(), | 357 std::move(nexe_file_), std::move(socket_for_renderer_), |
359 socket_for_renderer_.Pass(), | 358 std::move(socket_for_sel_ldr_), |
360 socket_for_sel_ldr_.Pass(), | |
361 }; | 359 }; |
362 // Open files need to be closed on the blocking pool. | 360 // Open files need to be closed on the blocking pool. |
363 for (auto& file : files_to_close) { | 361 for (auto& file : files_to_close) { |
364 if (file.IsValid()) { | 362 if (file.IsValid()) { |
365 content::BrowserThread::GetBlockingPool()->PostTask( | 363 content::BrowserThread::GetBlockingPool()->PostTask( |
366 FROM_HERE, | 364 FROM_HERE, base::Bind(&CloseFile, base::Passed(std::move(file)))); |
367 base::Bind(&CloseFile, base::Passed(file.Pass()))); | |
368 } | 365 } |
369 } | 366 } |
370 | 367 |
371 if (reply_msg_) { | 368 if (reply_msg_) { |
372 // The process failed to launch for some reason. | 369 // The process failed to launch for some reason. |
373 // Don't keep the renderer hanging. | 370 // Don't keep the renderer hanging. |
374 reply_msg_->set_reply_error(); | 371 reply_msg_->set_reply_error(); |
375 nacl_host_message_filter_->Send(reply_msg_); | 372 nacl_host_message_filter_->Send(reply_msg_); |
376 } | 373 } |
377 #if defined(OS_WIN) | 374 #if defined(OS_WIN) |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 if (RunningOnWOW64()) { | 741 if (RunningOnWOW64()) { |
745 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { | 742 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { |
746 SendErrorToRenderer("BrokerAddTargetPeer() failed"); | 743 SendErrorToRenderer("BrokerAddTargetPeer() failed"); |
747 return; | 744 return; |
748 } | 745 } |
749 } | 746 } |
750 #endif | 747 #endif |
751 | 748 |
752 // First, create an |imc_channel_handle| for the renderer. | 749 // First, create an |imc_channel_handle| for the renderer. |
753 IPC::PlatformFileForTransit imc_handle_for_renderer = | 750 IPC::PlatformFileForTransit imc_handle_for_renderer = |
754 IPC::TakeFileHandleForProcess(socket_for_renderer_.Pass(), | 751 IPC::TakeFileHandleForProcess(std::move(socket_for_renderer_), |
755 nacl_host_message_filter_->PeerHandle()); | 752 nacl_host_message_filter_->PeerHandle()); |
756 if (imc_handle_for_renderer == IPC::InvalidPlatformFileForTransit()) { | 753 if (imc_handle_for_renderer == IPC::InvalidPlatformFileForTransit()) { |
757 // Failed to create the handle. | 754 // Failed to create the handle. |
758 SendErrorToRenderer("imc_channel_handle creation failed."); | 755 SendErrorToRenderer("imc_channel_handle creation failed."); |
759 return; | 756 return; |
760 } | 757 } |
761 | 758 |
762 // Hereafter, we always send an IPC message with handles including imc_handle | 759 // Hereafter, we always send an IPC message with handles including imc_handle |
763 // created above which, on Windows, are not closable in this process. | 760 // created above which, on Windows, are not closable in this process. |
764 std::string error_message; | 761 std::string error_message; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 base::ProcessId pid = base::GetProcId(process_->GetData().handle); | 906 base::ProcessId pid = base::GetProcId(process_->GetData().handle); |
910 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; | 907 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; |
911 } | 908 } |
912 } else { | 909 } else { |
913 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); | 910 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); |
914 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); | 911 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); |
915 params.version = NaClBrowser::GetDelegate()->GetVersionString(); | 912 params.version = NaClBrowser::GetDelegate()->GetVersionString(); |
916 params.enable_debug_stub = enable_nacl_debug; | 913 params.enable_debug_stub = enable_nacl_debug; |
917 | 914 |
918 const ChildProcessData& data = process_->GetData(); | 915 const ChildProcessData& data = process_->GetData(); |
919 params.imc_bootstrap_handle = | 916 params.imc_bootstrap_handle = IPC::TakeFileHandleForProcess( |
920 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), data.handle); | 917 std::move(socket_for_sel_ldr_), data.handle); |
921 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) { | 918 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) { |
922 return false; | 919 return false; |
923 } | 920 } |
924 | 921 |
925 const base::File& irt_file = nacl_browser->IrtFile(); | 922 const base::File& irt_file = nacl_browser->IrtFile(); |
926 CHECK(irt_file.IsValid()); | 923 CHECK(irt_file.IsValid()); |
927 // Send over the IRT file handle. We don't close our own copy! | 924 // Send over the IRT file handle. We don't close our own copy! |
928 params.irt_handle = IPC::GetFileHandleForProcess( | 925 params.irt_handle = IPC::GetFileHandleForProcess( |
929 irt_file.GetPlatformFile(), data.handle, false); | 926 irt_file.GetPlatformFile(), data.handle, false); |
930 if (params.irt_handle == IPC::InvalidPlatformFileForTransit()) { | 927 if (params.irt_handle == IPC::InvalidPlatformFileForTransit()) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 } | 1021 } |
1025 | 1022 |
1026 void NaClProcessHost::StartNaClFileResolved( | 1023 void NaClProcessHost::StartNaClFileResolved( |
1027 NaClStartParams params, | 1024 NaClStartParams params, |
1028 const base::FilePath& file_path, | 1025 const base::FilePath& file_path, |
1029 base::File checked_nexe_file) { | 1026 base::File checked_nexe_file) { |
1030 if (checked_nexe_file.IsValid()) { | 1027 if (checked_nexe_file.IsValid()) { |
1031 // Release the file received from the renderer. This has to be done on a | 1028 // Release the file received from the renderer. This has to be done on a |
1032 // thread where IO is permitted, though. | 1029 // thread where IO is permitted, though. |
1033 content::BrowserThread::GetBlockingPool()->PostTask( | 1030 content::BrowserThread::GetBlockingPool()->PostTask( |
1034 FROM_HERE, | 1031 FROM_HERE, base::Bind(&CloseFile, base::Passed(std::move(nexe_file_)))); |
1035 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); | |
1036 params.nexe_file_path_metadata = file_path; | 1032 params.nexe_file_path_metadata = file_path; |
1037 params.nexe_file = IPC::TakeFileHandleForProcess( | 1033 params.nexe_file = IPC::TakeFileHandleForProcess( |
1038 checked_nexe_file.Pass(), process_->GetData().handle); | 1034 std::move(checked_nexe_file), process_->GetData().handle); |
1039 } else { | 1035 } else { |
1040 params.nexe_file = IPC::TakeFileHandleForProcess( | 1036 params.nexe_file = IPC::TakeFileHandleForProcess( |
1041 nexe_file_.Pass(), process_->GetData().handle); | 1037 std::move(nexe_file_), process_->GetData().handle); |
1042 } | 1038 } |
1043 | 1039 |
1044 #if defined(OS_LINUX) | 1040 #if defined(OS_LINUX) |
1045 // In Non-SFI mode, create socket pairs for IPC channels here, unlike in | 1041 // In Non-SFI mode, create socket pairs for IPC channels here, unlike in |
1046 // SFI-mode, in which those channels are created in nacl_listener.cc. | 1042 // SFI-mode, in which those channels are created in nacl_listener.cc. |
1047 // This is for security hardening. We can then prohibit the socketpair() | 1043 // This is for security hardening. We can then prohibit the socketpair() |
1048 // system call in nacl_helper and nacl_helper_nonsfi. | 1044 // system call in nacl_helper and nacl_helper_nonsfi. |
1049 if (uses_nonsfi_mode_) { | 1045 if (uses_nonsfi_mode_) { |
1050 // Note: here, because some FDs/handles for the NaCl loader process are | 1046 // Note: here, because some FDs/handles for the NaCl loader process are |
1051 // already opened, they are transferred to NaCl loader process even if | 1047 // already opened, they are transferred to NaCl loader process even if |
(...skipping 17 matching lines...) Expand all Loading... |
1069 &ppapi_renderer_client_channel_handle) || | 1065 &ppapi_renderer_client_channel_handle) || |
1070 !CreateChannelHandlePair(&trusted_service_server_channel_handle, | 1066 !CreateChannelHandlePair(&trusted_service_server_channel_handle, |
1071 &trusted_service_client_channel_handle) || | 1067 &trusted_service_client_channel_handle) || |
1072 !CreateChannelHandlePair(&manifest_service_server_channel_handle, | 1068 !CreateChannelHandlePair(&manifest_service_server_channel_handle, |
1073 &manifest_service_client_channel_handle)) { | 1069 &manifest_service_client_channel_handle)) { |
1074 SendErrorToRenderer("Failed to create socket pairs."); | 1070 SendErrorToRenderer("Failed to create socket pairs."); |
1075 has_error = true; | 1071 has_error = true; |
1076 } | 1072 } |
1077 | 1073 |
1078 if (!has_error && | 1074 if (!has_error && |
1079 !StartPPAPIProxy(ppapi_browser_client_channel_handle.Pass())) { | 1075 !StartPPAPIProxy(std::move(ppapi_browser_client_channel_handle))) { |
1080 SendErrorToRenderer("Failed to start browser PPAPI proxy."); | 1076 SendErrorToRenderer("Failed to start browser PPAPI proxy."); |
1081 has_error = true; | 1077 has_error = true; |
1082 } | 1078 } |
1083 | 1079 |
1084 if (!has_error) { | 1080 if (!has_error) { |
1085 // On success, send back a success message to the renderer process, | 1081 // On success, send back a success message to the renderer process, |
1086 // and transfer the channel handles for the NaCl loader process to | 1082 // and transfer the channel handles for the NaCl loader process to |
1087 // |params|. | 1083 // |params|. |
1088 ReplyToRenderer(ppapi_renderer_client_channel_handle.Pass(), | 1084 ReplyToRenderer(std::move(ppapi_renderer_client_channel_handle), |
1089 trusted_service_client_channel_handle.Pass(), | 1085 std::move(trusted_service_client_channel_handle), |
1090 manifest_service_client_channel_handle.Pass()); | 1086 std::move(manifest_service_client_channel_handle)); |
1091 params.ppapi_browser_channel_handle = | 1087 params.ppapi_browser_channel_handle = |
1092 ppapi_browser_server_channel_handle.release(); | 1088 ppapi_browser_server_channel_handle.release(); |
1093 params.ppapi_renderer_channel_handle = | 1089 params.ppapi_renderer_channel_handle = |
1094 ppapi_renderer_server_channel_handle.release(); | 1090 ppapi_renderer_server_channel_handle.release(); |
1095 params.trusted_service_channel_handle = | 1091 params.trusted_service_channel_handle = |
1096 trusted_service_server_channel_handle.release(); | 1092 trusted_service_server_channel_handle.release(); |
1097 params.manifest_service_channel_handle = | 1093 params.manifest_service_channel_handle = |
1098 manifest_service_server_channel_handle.release(); | 1094 manifest_service_server_channel_handle.release(); |
1099 } | 1095 } |
1100 } | 1096 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1190 const IPC::ChannelHandle& raw_manifest_service_channel_handle) { | 1186 const IPC::ChannelHandle& raw_manifest_service_channel_handle) { |
1191 ScopedChannelHandle ppapi_browser_channel_handle( | 1187 ScopedChannelHandle ppapi_browser_channel_handle( |
1192 raw_ppapi_browser_channel_handle); | 1188 raw_ppapi_browser_channel_handle); |
1193 ScopedChannelHandle ppapi_renderer_channel_handle( | 1189 ScopedChannelHandle ppapi_renderer_channel_handle( |
1194 raw_ppapi_renderer_channel_handle); | 1190 raw_ppapi_renderer_channel_handle); |
1195 ScopedChannelHandle trusted_renderer_channel_handle( | 1191 ScopedChannelHandle trusted_renderer_channel_handle( |
1196 raw_trusted_renderer_channel_handle); | 1192 raw_trusted_renderer_channel_handle); |
1197 ScopedChannelHandle manifest_service_channel_handle( | 1193 ScopedChannelHandle manifest_service_channel_handle( |
1198 raw_manifest_service_channel_handle); | 1194 raw_manifest_service_channel_handle); |
1199 | 1195 |
1200 if (!StartPPAPIProxy(ppapi_browser_channel_handle.Pass())) { | 1196 if (!StartPPAPIProxy(std::move(ppapi_browser_channel_handle))) { |
1201 SendErrorToRenderer("Browser PPAPI proxy could not start."); | 1197 SendErrorToRenderer("Browser PPAPI proxy could not start."); |
1202 return; | 1198 return; |
1203 } | 1199 } |
1204 | 1200 |
1205 // Let the renderer know that the IPC channels are established. | 1201 // Let the renderer know that the IPC channels are established. |
1206 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(), | 1202 ReplyToRenderer(std::move(ppapi_renderer_channel_handle), |
1207 trusted_renderer_channel_handle.Pass(), | 1203 std::move(trusted_renderer_channel_handle), |
1208 manifest_service_channel_handle.Pass()); | 1204 std::move(manifest_service_channel_handle)); |
1209 } | 1205 } |
1210 | 1206 |
1211 bool NaClProcessHost::StartWithLaunchedProcess() { | 1207 bool NaClProcessHost::StartWithLaunchedProcess() { |
1212 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 1208 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
1213 | 1209 |
1214 if (nacl_browser->IsReady()) { | 1210 if (nacl_browser->IsReady()) { |
1215 return StartNaClExecution(); | 1211 return StartNaClExecution(); |
1216 } else if (nacl_browser->IsOk()) { | 1212 } else if (nacl_browser->IsOk()) { |
1217 nacl_browser->WaitForResources( | 1213 nacl_browser->WaitForResources( |
1218 base::Bind(&NaClProcessHost::OnResourcesReady, | 1214 base::Bind(&NaClProcessHost::OnResourcesReady, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 | 1290 |
1295 void NaClProcessHost::FileResolved( | 1291 void NaClProcessHost::FileResolved( |
1296 uint64_t file_token_lo, | 1292 uint64_t file_token_lo, |
1297 uint64_t file_token_hi, | 1293 uint64_t file_token_hi, |
1298 const base::FilePath& file_path, | 1294 const base::FilePath& file_path, |
1299 base::File file) { | 1295 base::File file) { |
1300 base::FilePath out_file_path; | 1296 base::FilePath out_file_path; |
1301 IPC::PlatformFileForTransit out_handle; | 1297 IPC::PlatformFileForTransit out_handle; |
1302 if (file.IsValid()) { | 1298 if (file.IsValid()) { |
1303 out_file_path = file_path; | 1299 out_file_path = file_path; |
1304 out_handle = IPC::TakeFileHandleForProcess( | 1300 out_handle = IPC::TakeFileHandleForProcess(std::move(file), |
1305 file.Pass(), | 1301 process_->GetData().handle); |
1306 process_->GetData().handle); | |
1307 } else { | 1302 } else { |
1308 out_handle = IPC::InvalidPlatformFileForTransit(); | 1303 out_handle = IPC::InvalidPlatformFileForTransit(); |
1309 } | 1304 } |
1310 Send(new NaClProcessMsg_ResolveFileTokenReply( | 1305 Send(new NaClProcessMsg_ResolveFileTokenReply( |
1311 file_token_lo, | 1306 file_token_lo, |
1312 file_token_hi, | 1307 file_token_hi, |
1313 out_handle, | 1308 out_handle, |
1314 out_file_path)); | 1309 out_file_path)); |
1315 } | 1310 } |
1316 | 1311 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 NaClStartDebugExceptionHandlerThread( | 1373 NaClStartDebugExceptionHandlerThread( |
1379 process.Pass(), info, base::ThreadTaskRunnerHandle::Get(), | 1374 process.Pass(), info, base::ThreadTaskRunnerHandle::Get(), |
1380 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1375 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
1381 weak_factory_.GetWeakPtr())); | 1376 weak_factory_.GetWeakPtr())); |
1382 return true; | 1377 return true; |
1383 } | 1378 } |
1384 } | 1379 } |
1385 #endif | 1380 #endif |
1386 | 1381 |
1387 } // namespace nacl | 1382 } // namespace nacl |
OLD | NEW |