Chromium Code Reviews| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 | 187 |
| 188 void SetCloseOnExec(NaClHandle fd) { | 188 void SetCloseOnExec(NaClHandle fd) { |
| 189 #if defined(OS_POSIX) | 189 #if defined(OS_POSIX) |
| 190 int flags = fcntl(fd, F_GETFD); | 190 int flags = fcntl(fd, F_GETFD); |
| 191 CHECK_NE(flags, -1); | 191 CHECK_NE(flags, -1); |
| 192 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | 192 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
| 193 CHECK_EQ(rc, 0); | 193 CHECK_EQ(rc, 0); |
| 194 #endif | 194 #endif |
| 195 } | 195 } |
| 196 | 196 |
| 197 void CloseFile(base::File file) { | 197 void PostCloseFile(base::File file) { |
| 198 if (!file.IsValid()) { | |
| 199 return; | |
| 200 } | |
| 201 | |
| 198 // The base::File destructor will close the file for us. | 202 // The base::File destructor will close the file for us. |
| 203 content::BrowserThread::GetBlockingPool()->PostTask( | |
| 204 FROM_HERE, | |
| 205 base::Bind(&ignore_result<base::File>, base::Passed(&file))); | |
| 206 } | |
| 207 | |
| 208 // The maximum number of resource file handles NaClProcessMsg_Start message | |
| 209 // can have. Currently IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage | |
| 210 // is 128 and NaCl sends 5 handles for other purposes, hence 123. | |
| 211 const size_t kMaxPreOpenResourceFiles = 123; | |
| 212 | |
| 213 #if defined(OS_POSIX) | |
| 214 static_assert(kMaxPreOpenResourceFiles == | |
| 215 IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage - 5, | |
| 216 "kMaxPreOpenResourceFiles is not up to date"); | |
| 217 #endif | |
| 218 | |
| 219 void BatchOpenResourceFiles( | |
| 220 const std::vector<NaClResourcePrefetchRequest>& request_list, | |
| 221 const base::FilePath& profile_directory, | |
| 222 base::ProcessHandle target_process, | |
| 223 std::vector<NaClResourcePrefetchResult>* result_list) { | |
| 224 if (!result_list) { | |
| 225 // If output buffer is null, which means there is no resource to be opened. | |
| 226 // Do nothing, then. | |
| 227 DCHECK(request_list.empty()); | |
| 228 return; | |
| 229 } | |
| 230 | |
| 231 NaClBrowserDelegate* browser_delegate = NaClBrowser::GetDelegate(); | |
| 232 for (size_t i = 0; | |
| 233 i < request_list.size() && | |
| 234 result_list->size() < kMaxPreOpenResourceFiles; | |
| 235 ++i) { | |
| 236 base::FilePath file_path; | |
| 237 if (!browser_delegate->MapUrlToLocalFilePath( | |
| 238 GURL(request_list[i].resource_url), | |
| 239 true, // Use blocking API. | |
| 240 profile_directory, | |
| 241 &file_path)) { | |
| 242 continue; | |
| 243 } | |
| 244 | |
| 245 base::File file = OpenNaClReadExecImpl(file_path, true /* executable */); | |
| 246 if (!file.IsValid()) | |
| 247 continue; | |
| 248 | |
| 249 // Note: this runs only in Non-SFI mode. So, do not pass the file path; | |
| 250 // there's no validation caching in that case, so it's unnecessary. | |
| 251 // Moreover, it would expose the file path to the plugin. | |
| 252 result_list->push_back(NaClResourcePrefetchResult( | |
| 253 IPC::TakeFileHandleForProcess(file.Pass(), target_process), | |
| 254 base::FilePath(), | |
| 255 request_list[i].file_key)); | |
| 256 } | |
| 257 } | |
| 258 | |
| 259 base::File ReopenNexeFile( | |
| 260 base::File original_nexe_file, base::FilePath* nexe_file_path) { | |
| 261 // If no path is specified, use the original |nexe_file|. | |
| 262 if (!nexe_file_path || nexe_file_path->empty()) | |
| 263 return original_nexe_file.Pass(); | |
| 264 | |
| 265 // Reopen the nexe file. | |
| 266 base::File reopened_nexe_file = OpenNaClReadExecImpl( | |
| 267 *nexe_file_path, true /* executable */); | |
| 268 if (!reopened_nexe_file.IsValid()) { | |
| 269 // On fail, clear the path, which will eventually passed to the loader. | |
| 270 nexe_file_path->clear(); | |
| 271 return original_nexe_file.Pass(); | |
| 272 } | |
| 273 | |
| 274 // Note that, the |original_nexe_file| will be closed automatically. | |
| 275 return reopened_nexe_file.Pass(); | |
| 276 } | |
| 277 | |
| 278 // StartNaClExecution needs file operations. This function takes it, and | |
| 279 // should run on blocking pool. | |
| 280 base::File ResolveNaClFile( | |
| 281 base::FilePath* nexe_file_path, | |
| 282 base::File nexe_file, | |
| 283 const std::vector<NaClResourcePrefetchRequest>& | |
| 284 resource_prefetch_request_list, | |
| 285 const base::FilePath& profile_directory, | |
| 286 base::ProcessHandle target_process, | |
| 287 std::vector<NaClResourcePrefetchResult>* prefetched_resource_files) { | |
| 288 BatchOpenResourceFiles(resource_prefetch_request_list, | |
| 289 profile_directory, | |
| 290 target_process, | |
| 291 prefetched_resource_files); | |
| 292 return ReopenNexeFile(nexe_file.Pass(), nexe_file_path); | |
| 199 } | 293 } |
| 200 | 294 |
| 201 } // namespace | 295 } // namespace |
| 202 | 296 |
| 203 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = | 297 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = |
| 204 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds; | 298 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds; |
| 205 | 299 |
| 206 NaClProcessHost::NaClProcessHost( | 300 NaClProcessHost::NaClProcessHost( |
| 207 const GURL& manifest_url, | 301 const GURL& manifest_url, |
| 208 base::File nexe_file, | 302 base::File nexe_file, |
| 209 const NaClFileToken& nexe_token, | 303 const NaClFileToken& nexe_token, |
| 210 const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, | 304 const std::vector<NaClResourcePrefetchRequest>& |
| 305 resource_prefetch_request_list, | |
| 211 ppapi::PpapiPermissions permissions, | 306 ppapi::PpapiPermissions permissions, |
| 212 int render_view_id, | 307 int render_view_id, |
| 213 uint32 permission_bits, | 308 uint32 permission_bits, |
| 214 bool uses_nonsfi_mode, | 309 bool uses_nonsfi_mode, |
| 215 bool off_the_record, | 310 bool off_the_record, |
| 216 NaClAppProcessType process_type, | 311 NaClAppProcessType process_type, |
| 217 const base::FilePath& profile_directory) | 312 const base::FilePath& profile_directory) |
| 218 : manifest_url_(manifest_url), | 313 : manifest_url_(manifest_url), |
| 219 nexe_file_(nexe_file.Pass()), | 314 nexe_file_(nexe_file.Pass()), |
| 220 nexe_token_(nexe_token), | 315 nexe_token_(nexe_token), |
| 221 prefetched_resource_files_(prefetched_resource_files), | 316 resource_prefetch_request_list_(resource_prefetch_request_list), |
| 222 permissions_(permissions), | 317 permissions_(permissions), |
| 223 #if defined(OS_WIN) | 318 #if defined(OS_WIN) |
| 224 process_launched_by_broker_(false), | 319 process_launched_by_broker_(false), |
| 225 #endif | 320 #endif |
| 226 reply_msg_(NULL), | 321 reply_msg_(NULL), |
| 227 #if defined(OS_WIN) | 322 #if defined(OS_WIN) |
| 228 debug_exception_handler_requested_(false), | 323 debug_exception_handler_requested_(false), |
| 229 #endif | 324 #endif |
| 230 uses_nonsfi_mode_(uses_nonsfi_mode), | 325 uses_nonsfi_mode_(uses_nonsfi_mode), |
| 231 enable_debug_stub_(false), | 326 enable_debug_stub_(false), |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 244 // for this use case. | 339 // for this use case. |
| 245 process_->SetName(net::FormatUrl(manifest_url_, std::string())); | 340 process_->SetName(net::FormatUrl(manifest_url_, std::string())); |
| 246 | 341 |
| 247 enable_debug_stub_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 342 enable_debug_stub_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 248 switches::kEnableNaClDebug); | 343 switches::kEnableNaClDebug); |
| 249 DCHECK(process_type_ != kUnknownNaClProcessType); | 344 DCHECK(process_type_ != kUnknownNaClProcessType); |
| 250 enable_crash_throttling_ = process_type_ != kNativeNaClProcessType; | 345 enable_crash_throttling_ = process_type_ != kNativeNaClProcessType; |
| 251 } | 346 } |
| 252 | 347 |
| 253 NaClProcessHost::~NaClProcessHost() { | 348 NaClProcessHost::~NaClProcessHost() { |
| 349 PostCloseFile(nexe_file_.Pass()); | |
| 350 PostCloseFile(socket_for_renderer_.Pass()); | |
| 351 PostCloseFile(socket_for_sel_ldr_.Pass()); | |
| 352 | |
| 254 // Report exit status only if the process was successfully started. | 353 // Report exit status only if the process was successfully started. |
| 255 if (process_->GetData().handle != base::kNullProcessHandle) { | 354 if (process_->GetData().handle != base::kNullProcessHandle) { |
| 256 int exit_code = 0; | 355 int exit_code = 0; |
| 257 process_->GetTerminationStatus(false /* known_dead */, &exit_code); | 356 process_->GetTerminationStatus(false /* known_dead */, &exit_code); |
| 258 std::string message = | 357 std::string message = |
| 259 base::StringPrintf("NaCl process exited with status %i (0x%x)", | 358 base::StringPrintf("NaCl process exited with status %i (0x%x)", |
| 260 exit_code, exit_code); | 359 exit_code, exit_code); |
| 261 if (exit_code == 0) { | 360 if (exit_code == 0) { |
| 262 VLOG(1) << message; | 361 VLOG(1) << message; |
| 263 } else { | 362 } else { |
| 264 LOG(ERROR) << message; | 363 LOG(ERROR) << message; |
| 265 } | 364 } |
| 266 NaClBrowser::GetInstance()->OnProcessEnd(process_->GetData().id); | 365 NaClBrowser::GetInstance()->OnProcessEnd(process_->GetData().id); |
| 267 } | 366 } |
| 268 | 367 |
| 269 // Note: this does not work on Windows, though we currently support this | |
| 270 // prefetching feature only on Non-SFI mode, which is supported only on | |
| 271 // Linux/ChromeOS, so it should be ok. | |
| 272 #if defined(OS_WIN) | |
| 273 DCHECK(prefetched_resource_files_.empty()); | |
| 274 #else | |
| 275 for (size_t i = 0; i < prefetched_resource_files_.size(); ++i) { | |
| 276 // The process failed to launch for some reason. Close resource file | |
| 277 // handles. | |
| 278 base::File file(IPC::PlatformFileForTransitToFile( | |
| 279 prefetched_resource_files_[i].file)); | |
| 280 content::BrowserThread::GetBlockingPool()->PostTask( | |
| 281 FROM_HERE, | |
| 282 base::Bind(&CloseFile, base::Passed(file.Pass()))); | |
| 283 } | |
| 284 #endif | |
| 285 | |
| 286 if (reply_msg_) { | 368 if (reply_msg_) { |
| 287 // The process failed to launch for some reason. | 369 // The process failed to launch for some reason. |
| 288 // Don't keep the renderer hanging. | 370 // Don't keep the renderer hanging. |
| 289 reply_msg_->set_reply_error(); | 371 reply_msg_->set_reply_error(); |
| 290 nacl_host_message_filter_->Send(reply_msg_); | 372 nacl_host_message_filter_->Send(reply_msg_); |
| 291 } | 373 } |
| 292 #if defined(OS_WIN) | 374 #if defined(OS_WIN) |
| 293 if (process_launched_by_broker_) { | 375 if (process_launched_by_broker_) { |
| 294 NaClBrokerService::GetInstance()->OnLoaderDied(); | 376 NaClBrokerService::GetInstance()->OnLoaderDied(); |
| 295 } | 377 } |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 792 bool NaClProcessHost::StartNaClExecution() { | 874 bool NaClProcessHost::StartNaClExecution() { |
| 793 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 875 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 794 | 876 |
| 795 NaClStartParams params; | 877 NaClStartParams params; |
| 796 | 878 |
| 797 // Enable PPAPI proxy channel creation only for renderer processes. | 879 // Enable PPAPI proxy channel creation only for renderer processes. |
| 798 params.enable_ipc_proxy = enable_ppapi_proxy(); | 880 params.enable_ipc_proxy = enable_ppapi_proxy(); |
| 799 params.process_type = process_type_; | 881 params.process_type = process_type_; |
| 800 bool enable_nacl_debug = enable_debug_stub_ && | 882 bool enable_nacl_debug = enable_debug_stub_ && |
| 801 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); | 883 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); |
| 884 #if defined(OS_MACOSX) | |
| 885 base::ScopedFD memory_fd; | |
| 886 #endif // defined(OS_MACOSX) | |
| 887 #if defined(OS_POSIX) | |
| 888 base::ScopedFD debug_stub_server_bound_socket; | |
| 889 #endif // defined(OS_POSIX) | |
| 890 | |
| 802 if (uses_nonsfi_mode_) { | 891 if (uses_nonsfi_mode_) { |
| 803 // Currently, non-SFI mode is supported only on Linux. | 892 // Currently, non-SFI mode is supported only on Linux. |
| 804 #if defined(OS_LINUX) | 893 #if defined(OS_LINUX) |
| 805 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is | 894 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is |
| 806 // not created. | 895 // not created. |
| 807 DCHECK(!socket_for_sel_ldr_.IsValid()); | 896 DCHECK(!socket_for_sel_ldr_.IsValid()); |
| 808 #endif | 897 #endif |
| 809 if (enable_nacl_debug) { | 898 if (enable_nacl_debug) { |
| 810 base::ProcessId pid = base::GetProcId(process_->GetData().handle); | 899 base::ProcessId pid = base::GetProcId(process_->GetData().handle); |
| 811 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; | 900 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; |
| 812 } | 901 } |
| 813 } else { | 902 } else { |
| 814 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); | 903 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); |
| 815 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); | 904 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); |
| 816 params.version = NaClBrowser::GetDelegate()->GetVersionString(); | 905 params.version = NaClBrowser::GetDelegate()->GetVersionString(); |
| 817 params.enable_debug_stub = enable_nacl_debug; | 906 params.enable_debug_stub = enable_nacl_debug; |
| 818 | 907 |
| 819 const ChildProcessData& data = process_->GetData(); | 908 CHECK(nacl_browser->IrtFile().IsValid()); |
| 820 params.imc_bootstrap_handle = | |
| 821 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), data.handle); | |
| 822 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) { | |
| 823 return false; | |
| 824 } | |
| 825 | |
| 826 const base::File& irt_file = nacl_browser->IrtFile(); | |
| 827 CHECK(irt_file.IsValid()); | |
| 828 // Send over the IRT file handle. We don't close our own copy! | |
| 829 params.irt_handle = IPC::GetFileHandleForProcess( | |
| 830 irt_file.GetPlatformFile(), data.handle, false); | |
| 831 if (params.irt_handle == IPC::InvalidPlatformFileForTransit()) { | |
| 832 return false; | |
| 833 } | |
| 834 | 909 |
| 835 #if defined(OS_MACOSX) | 910 #if defined(OS_MACOSX) |
| 836 // For dynamic loading support, NaCl requires a file descriptor that | 911 // For dynamic loading support, NaCl requires a file descriptor that |
| 837 // was created in /tmp, since those created with shm_open() are not | 912 // was created in /tmp, since those created with shm_open() are not |
| 838 // mappable with PROT_EXEC. Rather than requiring an extra IPC | 913 // mappable with PROT_EXEC. Rather than requiring an extra IPC |
| 839 // round trip out of the sandbox, we create an FD here. | 914 // round trip out of the sandbox, we create an FD here. |
| 840 base::SharedMemory memory_buffer; | 915 base::SharedMemory memory_buffer; |
| 841 base::SharedMemoryCreateOptions options; | 916 base::SharedMemoryCreateOptions options; |
| 842 options.size = 1; | 917 options.size = 1; |
| 843 options.executable = true; | 918 options.executable = true; |
| 844 if (!memory_buffer.Create(options)) { | 919 if (!memory_buffer.Create(options)) { |
| 845 DLOG(ERROR) << "Failed to allocate memory buffer"; | 920 DLOG(ERROR) << "Failed to allocate memory buffer"; |
| 846 return false; | 921 return false; |
| 847 } | 922 } |
| 848 base::ScopedFD memory_fd(dup(memory_buffer.handle().fd)); | 923 memory_fd.reset(dup(memory_buffer.handle().fd)); |
| 849 if (!memory_fd.is_valid()) { | 924 if (!memory_fd.is_valid()) { |
| 850 DLOG(ERROR) << "Failed to dup() a file descriptor"; | 925 DLOG(ERROR) << "Failed to dup() a file descriptor"; |
| 851 return false; | 926 return false; |
| 852 } | 927 } |
| 853 params.mac_shm_fd = IPC::GetFileHandleForProcess( | |
| 854 memory_fd.release(), data.handle, true); | |
| 855 #endif | 928 #endif |
| 856 | 929 |
| 857 #if defined(OS_POSIX) | 930 #if defined(OS_POSIX) |
| 858 if (params.enable_debug_stub) { | 931 if (params.enable_debug_stub) |
| 859 net::SocketDescriptor server_bound_socket = GetDebugStubSocketHandle(); | 932 debug_stub_server_bound_socket.reset(GetDebugStubSocketHandle()); |
| 860 if (server_bound_socket != net::kInvalidSocket) { | |
| 861 params.debug_stub_server_bound_socket = IPC::GetFileHandleForProcess( | |
| 862 server_bound_socket, data.handle, true); | |
| 863 } | |
| 864 } | |
| 865 #endif | 933 #endif |
| 866 } | 934 } |
| 867 | 935 |
| 868 if (!crash_info_shmem_.ShareToProcess(process_->GetData().handle, | 936 // Transfer resources to |params|. |
| 869 ¶ms.crash_info_shmem_handle)) { | 937 // Hereafter, we should never return false, and should always send an IPC |
| 870 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; | 938 // to NaCl plugin process. Otherwise, the resources passed to |params| may |
| 871 return false; | 939 // be leaked. Note that these are resources for Plugin process, so we |
| 940 // cannot properly release those in this (browser) process. | |
| 941 { | |
| 942 const ChildProcessData& data = process_->GetData(); | |
| 943 if (!uses_nonsfi_mode_) { | |
| 944 params.imc_bootstrap_handle = IPC::TakeFileHandleForProcess( | |
| 945 socket_for_sel_ldr_.Pass(), data.handle); | |
| 946 // Send over the IRT file handle. We don't close our own copy! | |
| 947 params.irt_handle = IPC::GetFileHandleForProcess( | |
|
Mark Seaborn
2015/05/08 00:02:02
So you're changing the browser process to no longe
hidehiko
2015/05/11 16:52:49
My intention is "deferring the error handling to t
Mark Seaborn
2015/05/25 19:48:55
OK. If you want to say that the NaClProcessMsg_St
hidehiko
2015/05/26 14:32:59
Done.
| |
| 948 nacl_browser->IrtFile().GetPlatformFile(), data.handle, false); | |
| 949 | |
| 950 #if defined(OS_MACOSX) | |
| 951 params.mac_shm_fd = IPC::GetFileHandleForProcess( | |
| 952 memory_fd.release(), data.handle, true); | |
| 953 #endif | |
| 954 #if defined(OS_POSIX) | |
| 955 params.debug_stub_server_bound_socket = IPC::GetFileHandleForProcess( | |
| 956 debug_stub_server_bound_socket.release(), data.handle, true); | |
| 957 #endif | |
| 958 } | |
| 959 | |
| 960 if (!crash_info_shmem_.ShareToProcess(data.handle, | |
| 961 ¶ms.crash_info_shmem_handle)) { | |
| 962 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; | |
| 963 // Do not return here. | |
| 964 } | |
| 872 } | 965 } |
| 873 | 966 |
| 874 base::FilePath file_path; | 967 // We have to reopen the file in the browser process; we don't want a |
| 875 if (uses_nonsfi_mode_) { | 968 // compromised renderer to pass an arbitrary fd that could get loaded |
| 876 // Don't retrieve the file path when using nonsfi mode; there's no | 969 // into the plugin process. |
| 877 // validation caching in that case, so it's unnecessary work, and would | 970 // Don't retrieve the file path when using nonsfi mode; there's no |
| 878 // expose the file path to the plugin. | 971 // validation caching in that case, so it's unnecessary work, and would |
| 879 | 972 // expose the file path to the plugin. |
| 880 // Pass the pre-opened resource files to the loader. For the same reason | 973 scoped_ptr<base::FilePath> nexe_file_path; |
| 881 // as above, use an empty base::FilePath. | 974 if (!uses_nonsfi_mode_) { |
| 882 for (size_t i = 0; i < prefetched_resource_files_.size(); ++i) { | 975 nexe_file_path.reset(new base::FilePath); |
| 883 params.prefetched_resource_files.push_back(NaClResourcePrefetchResult( | 976 if (!NaClBrowser::GetInstance()->GetFilePath( |
| 884 prefetched_resource_files_[i].file, | 977 nexe_token_.lo, nexe_token_.hi, nexe_file_path.get())) { |
| 885 base::FilePath(), | 978 // Failed. Reset the pointer. |
| 886 prefetched_resource_files_[i].file_key)); | 979 nexe_file_path.reset(); |
| 887 } | 980 } |
| 888 prefetched_resource_files_.clear(); | |
| 889 } else { | |
| 890 if (NaClBrowser::GetInstance()->GetFilePath(nexe_token_.lo, | |
| 891 nexe_token_.hi, | |
| 892 &file_path)) { | |
| 893 // We have to reopen the file in the browser process; we don't want a | |
| 894 // compromised renderer to pass an arbitrary fd that could get loaded | |
| 895 // into the plugin process. | |
| 896 if (base::PostTaskAndReplyWithResult( | |
| 897 content::BrowserThread::GetBlockingPool(), | |
| 898 FROM_HERE, | |
| 899 base::Bind(OpenNaClReadExecImpl, | |
| 900 file_path, | |
| 901 true /* is_executable */), | |
| 902 base::Bind(&NaClProcessHost::StartNaClFileResolved, | |
| 903 weak_factory_.GetWeakPtr(), | |
| 904 params, | |
| 905 file_path))) { | |
| 906 return true; | |
| 907 } | |
| 908 } | |
| 909 // TODO(yusukes): Handle |prefetched_resource_files_| for SFI-NaCl. | |
| 910 DCHECK(prefetched_resource_files_.empty()); | |
| 911 } | 981 } |
| 912 | 982 |
| 913 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), | 983 // Pass the pre-opened resource files to the loader. |
| 914 process_->GetData().handle); | 984 scoped_ptr<std::vector<NaClResourcePrefetchResult> > |
| 915 process_->Send(new NaClProcessMsg_Start(params)); | 985 prefetched_resource_files; |
| 986 if (!resource_prefetch_request_list_.empty()) { | |
| 987 // TODO(yusukes): Handle |resource_prefetch_request_list_| for SFI-NaCl. | |
| 988 DCHECK(uses_nonsfi_mode_); | |
| 989 prefetched_resource_files.reset( | |
| 990 new std::vector<NaClResourcePrefetchResult>); | |
| 991 } | |
| 992 | |
| 993 // If file operation is necessary, run it on a blocking pool, where file | |
| 994 // operations are allowed. | |
| 995 if (nexe_file_path.get() || prefetched_resource_files.get()) { | |
| 996 if (base::PostTaskAndReplyWithResult( | |
| 997 content::BrowserThread::GetBlockingPool(), | |
| 998 FROM_HERE, | |
| 999 base::Bind(&ResolveNaClFile, | |
| 1000 nexe_file_path.get(), | |
| 1001 base::Passed(&nexe_file_), | |
| 1002 resource_prefetch_request_list_, | |
| 1003 profile_directory_, | |
| 1004 process_->GetData().handle, | |
| 1005 prefetched_resource_files.get()), | |
| 1006 base::Bind(&NaClProcessHost::StartNaClExecutionAfterFileResolved, | |
| 1007 weak_factory_.GetWeakPtr(), | |
| 1008 params, | |
| 1009 base::Passed(&nexe_file_path), | |
| 1010 base::Passed(&prefetched_resource_files)))) { | |
| 1011 return true; | |
| 1012 } | |
| 1013 } | |
| 1014 | |
| 1015 StartNaClExecutionAfterFileResolved( | |
| 1016 params, | |
| 1017 scoped_ptr<base::FilePath>(), | |
| 1018 scoped_ptr<std::vector<NaClResourcePrefetchResult> >(), | |
| 1019 nexe_file_.Pass()); | |
| 916 return true; | 1020 return true; |
| 917 } | 1021 } |
| 918 | 1022 |
| 919 void NaClProcessHost::StartNaClFileResolved( | 1023 void NaClProcessHost::StartNaClExecutionAfterFileResolved( |
| 920 NaClStartParams params, | 1024 NaClStartParams params, |
| 921 const base::FilePath& file_path, | 1025 scoped_ptr<base::FilePath> nexe_file_path, |
| 922 base::File checked_nexe_file) { | 1026 scoped_ptr<std::vector<NaClResourcePrefetchResult> > |
| 923 if (checked_nexe_file.IsValid()) { | 1027 prefetched_resource_files, |
| 924 // Release the file received from the renderer. This has to be done on a | 1028 base::File nexe_file) { |
| 925 // thread where IO is permitted, though. | 1029 // Pass the nexe file and its path to params. |
| 926 content::BrowserThread::GetBlockingPool()->PostTask( | 1030 params.nexe_file = IPC::TakeFileHandleForProcess( |
| 927 FROM_HERE, | 1031 nexe_file.Pass(), process_->GetData().handle); |
| 928 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); | 1032 if (nexe_file_path.get()) { |
| 929 params.nexe_file_path_metadata = file_path; | 1033 params.nexe_file_path_metadata = *nexe_file_path; |
| 930 params.nexe_file = IPC::TakeFileHandleForProcess( | |
| 931 checked_nexe_file.Pass(), process_->GetData().handle); | |
| 932 } else { | |
| 933 params.nexe_file = IPC::TakeFileHandleForProcess( | |
| 934 nexe_file_.Pass(), process_->GetData().handle); | |
| 935 } | 1034 } |
| 1035 | |
| 1036 // Pass prefetched resources to params. | |
| 1037 if (prefetched_resource_files.get()) { | |
| 1038 prefetched_resource_files->swap(params.prefetched_resource_files); | |
| 1039 } | |
| 1040 | |
| 936 process_->Send(new NaClProcessMsg_Start(params)); | 1041 process_->Send(new NaClProcessMsg_Start(params)); |
| 937 } | 1042 } |
| 938 | 1043 |
| 939 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is | 1044 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is |
| 940 // received. | 1045 // received. |
| 941 void NaClProcessHost::OnPpapiChannelsCreated( | 1046 void NaClProcessHost::OnPpapiChannelsCreated( |
| 942 const IPC::ChannelHandle& browser_channel_handle, | 1047 const IPC::ChannelHandle& browser_channel_handle, |
| 943 const IPC::ChannelHandle& ppapi_renderer_channel_handle, | 1048 const IPC::ChannelHandle& ppapi_renderer_channel_handle, |
| 944 const IPC::ChannelHandle& trusted_renderer_channel_handle, | 1049 const IPC::ChannelHandle& trusted_renderer_channel_handle, |
| 945 const IPC::ChannelHandle& manifest_service_channel_handle) { | 1050 const IPC::ChannelHandle& manifest_service_channel_handle) { |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1180 process.Pass(), info, | 1285 process.Pass(), info, |
| 1181 base::MessageLoopProxy::current(), | 1286 base::MessageLoopProxy::current(), |
| 1182 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1287 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
| 1183 weak_factory_.GetWeakPtr())); | 1288 weak_factory_.GetWeakPtr())); |
| 1184 return true; | 1289 return true; |
| 1185 } | 1290 } |
| 1186 } | 1291 } |
| 1187 #endif | 1292 #endif |
| 1188 | 1293 |
| 1189 } // namespace nacl | 1294 } // namespace nacl |
| OLD | NEW |