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 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, | 625 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, |
| 626 OnPpapiChannelsCreated) | 626 OnPpapiChannelsCreated) |
| 627 IPC_MESSAGE_UNHANDLED(handled = false) | 627 IPC_MESSAGE_UNHANDLED(handled = false) |
| 628 IPC_END_MESSAGE_MAP() | 628 IPC_END_MESSAGE_MAP() |
| 629 } else { | 629 } else { |
| 630 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) | 630 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) |
| 631 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, | 631 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, |
| 632 OnQueryKnownToValidate) | 632 OnQueryKnownToValidate) |
| 633 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, | 633 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, |
| 634 OnSetKnownToValidate) | 634 OnSetKnownToValidate) |
| 635 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_ResolveFileToken, | |
| 636 OnResolveFileToken) | |
| 637 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileTokenAsync, | 635 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileTokenAsync, |
| 638 OnResolveFileTokenAsync) | 636 OnResolveFileTokenAsync) |
| 639 | 637 |
| 640 #if defined(OS_WIN) | 638 #if defined(OS_WIN) |
| 641 IPC_MESSAGE_HANDLER_DELAY_REPLY( | 639 IPC_MESSAGE_HANDLER_DELAY_REPLY( |
| 642 NaClProcessMsg_AttachDebugExceptionHandler, | 640 NaClProcessMsg_AttachDebugExceptionHandler, |
| 643 OnAttachDebugExceptionHandler) | 641 OnAttachDebugExceptionHandler) |
| 644 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected, | 642 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected, |
| 645 OnDebugStubPortSelected) | 643 OnDebugStubPortSelected) |
| 646 #endif | 644 #endif |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 815 // not created. | 813 // not created. |
| 816 DCHECK(!socket_for_sel_ldr_.IsValid()); | 814 DCHECK(!socket_for_sel_ldr_.IsValid()); |
| 817 #endif | 815 #endif |
| 818 } else { | 816 } else { |
| 819 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); | 817 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); |
| 820 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); | 818 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); |
| 821 params.version = NaClBrowser::GetDelegate()->GetVersionString(); | 819 params.version = NaClBrowser::GetDelegate()->GetVersionString(); |
| 822 params.enable_debug_stub = enable_debug_stub_ && | 820 params.enable_debug_stub = enable_debug_stub_ && |
| 823 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); | 821 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); |
| 824 | 822 |
| 825 // TODO(teravest): Resolve the file tokens right now instead of making the | |
| 826 // loader send IPC to resolve them later. | |
| 827 params.nexe_token_lo = nexe_token_.lo; | |
| 828 params.nexe_token_hi = nexe_token_.hi; | |
| 829 | |
| 830 const ChildProcessData& data = process_->GetData(); | 823 const ChildProcessData& data = process_->GetData(); |
| 831 if (!ShareHandleToSelLdr(data.handle, | 824 if (!ShareHandleToSelLdr(data.handle, |
| 832 socket_for_sel_ldr_.TakePlatformFile(), | 825 socket_for_sel_ldr_.TakePlatformFile(), |
| 833 true, | 826 true, |
| 834 ¶ms.handles)) { | 827 ¶ms.handles)) { |
| 835 return false; | 828 return false; |
| 836 } | 829 } |
| 837 | 830 |
| 838 // Currently, everything uses the IRT except for the PNaCl Translators. | 831 // Currently, everything uses the IRT except for the PNaCl Translators. |
| 839 bool uses_irt = process_type_ != kPNaClTranslatorProcessType; | 832 bool uses_irt = process_type_ != kPNaClTranslatorProcessType; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 874 if (params.enable_debug_stub) { | 867 if (params.enable_debug_stub) { |
| 875 net::SocketDescriptor server_bound_socket = GetDebugStubSocketHandle(); | 868 net::SocketDescriptor server_bound_socket = GetDebugStubSocketHandle(); |
| 876 if (server_bound_socket != net::kInvalidSocket) { | 869 if (server_bound_socket != net::kInvalidSocket) { |
| 877 params.debug_stub_server_bound_socket = | 870 params.debug_stub_server_bound_socket = |
| 878 FileDescriptor(server_bound_socket, true); | 871 FileDescriptor(server_bound_socket, true); |
| 879 } | 872 } |
| 880 } | 873 } |
| 881 #endif | 874 #endif |
| 882 } | 875 } |
| 883 | 876 |
| 884 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), | |
| 885 process_->GetData().handle); | |
| 886 if (!crash_info_shmem_.ShareToProcess(process_->GetData().handle, | 877 if (!crash_info_shmem_.ShareToProcess(process_->GetData().handle, |
| 887 ¶ms.crash_info_shmem_handle)) { | 878 ¶ms.crash_info_shmem_handle)) { |
| 888 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; | 879 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; |
| 889 return false; | 880 return false; |
| 890 } | 881 } |
| 891 | 882 |
| 883 base::FilePath file_path; | |
| 884 if (NaClBrowser::GetInstance()->GetFilePath(nexe_token_.lo, | |
| 885 nexe_token_.hi, | |
| 886 &file_path)) { | |
| 887 // We have to reopen the file in the browser process; we don't want a | |
| 888 // compromised renderer to pass an arbitrary fd that could get loaded | |
| 889 // into the plugin process. | |
| 890 if (base::PostTaskAndReplyWithResult( | |
| 891 content::BrowserThread::GetBlockingPool(), | |
| 892 FROM_HERE, | |
| 893 base::Bind(OpenNaClReadExecImpl, | |
| 894 file_path, | |
| 895 true /* is_executable */), | |
| 896 base::Bind(&NaClProcessHost::StartNaClFileResolved, | |
| 897 weak_factory_.GetWeakPtr(), | |
| 898 params, | |
| 899 file_path))) { | |
| 900 return true; | |
| 901 } | |
| 902 } | |
| 903 | |
| 904 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), | |
| 905 process_->GetData().handle); | |
| 892 process_->Send(new NaClProcessMsg_Start(params)); | 906 process_->Send(new NaClProcessMsg_Start(params)); |
| 893 return true; | 907 return true; |
| 894 } | 908 } |
| 895 | 909 |
| 910 void ClosePlatformFile(base::PlatformFile file) { | |
|
Mark Seaborn
2014/10/14 17:37:24
Shouldn't this be in an anon namespace? Doesn't b
teravest
2014/10/14 18:15:00
I've moved this to an anonymous namespace and chan
| |
| 911 #if defined(OS_WIN) | |
| 912 ::CloseHandle(file); | |
| 913 #elif defined(OS_POSIX) | |
| 914 IGNORE_EINTR(::close(file)); | |
| 915 #endif | |
| 916 } | |
| 917 | |
| 918 void NaClProcessHost::StartNaClFileResolved( | |
| 919 NaClStartParams params, | |
| 920 const base::FilePath& file_path, | |
| 921 base::File nexe_file) { | |
| 922 if (nexe_file.IsValid()) { | |
| 923 // Release the file received from the renderer. This has to be done on a | |
| 924 // thread where IO is permitted, though. | |
| 925 base::File close_nexe_file = nexe_file_.Pass(); | |
| 926 content::BrowserThread::GetBlockingPool()->PostTask( | |
| 927 FROM_HERE, | |
| 928 base::Bind(&ClosePlatformFile, close_nexe_file.TakePlatformFile())); | |
| 929 params.nexe_file_path = file_path; | |
| 930 params.nexe_file = IPC::TakeFileHandleForProcess( | |
| 931 nexe_file.Pass(), process_->GetData().handle); | |
| 932 } else { | |
| 933 params.nexe_file = IPC::TakeFileHandleForProcess( | |
| 934 nexe_file_.Pass(), process_->GetData().handle); | |
| 935 } | |
| 936 process_->Send(new NaClProcessMsg_Start(params)); | |
| 937 } | |
| 938 | |
| 896 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is | 939 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is |
| 897 // received. | 940 // received. |
| 898 void NaClProcessHost::OnPpapiChannelsCreated( | 941 void NaClProcessHost::OnPpapiChannelsCreated( |
| 899 const IPC::ChannelHandle& browser_channel_handle, | 942 const IPC::ChannelHandle& browser_channel_handle, |
| 900 const IPC::ChannelHandle& ppapi_renderer_channel_handle, | 943 const IPC::ChannelHandle& ppapi_renderer_channel_handle, |
| 901 const IPC::ChannelHandle& trusted_renderer_channel_handle, | 944 const IPC::ChannelHandle& trusted_renderer_channel_handle, |
| 902 const IPC::ChannelHandle& manifest_service_channel_handle) { | 945 const IPC::ChannelHandle& manifest_service_channel_handle) { |
| 903 if (!enable_ppapi_proxy()) { | 946 if (!enable_ppapi_proxy()) { |
| 904 ReplyToRenderer(IPC::ChannelHandle(), | 947 ReplyToRenderer(IPC::ChannelHandle(), |
| 905 trusted_renderer_channel_handle, | 948 trusted_renderer_channel_handle, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 988 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 1031 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 989 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); | 1032 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); |
| 990 } | 1033 } |
| 991 | 1034 |
| 992 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { | 1035 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { |
| 993 CHECK(!uses_nonsfi_mode_); | 1036 CHECK(!uses_nonsfi_mode_); |
| 994 NaClBrowser::GetInstance()->SetKnownToValidate( | 1037 NaClBrowser::GetInstance()->SetKnownToValidate( |
| 995 signature, off_the_record_); | 1038 signature, off_the_record_); |
| 996 } | 1039 } |
| 997 | 1040 |
| 998 void NaClProcessHost::OnResolveFileToken(uint64 file_token_lo, | 1041 void NaClProcessHost::OnResolveFileTokenAsync(uint64 file_token_lo, |
| 999 uint64 file_token_hi, | 1042 uint64 file_token_hi) { |
| 1000 IPC::Message* reply_msg) { | |
| 1001 // Was the file registered? | 1043 // Was the file registered? |
| 1002 // | 1044 // |
| 1003 // Note that the file path cache is of bounded size, and old entries can get | 1045 // Note that the file path cache is of bounded size, and old entries can get |
| 1004 // evicted. If a large number of NaCl modules are being launched at once, | 1046 // evicted. If a large number of NaCl modules are being launched at once, |
| 1005 // resolving the file_token may fail because the path cache was thrashed | 1047 // resolving the file_token may fail because the path cache was thrashed |
| 1006 // while the file_token was in flight. In this case the query fails, and we | 1048 // while the file_token was in flight. In this case the query fails, and we |
| 1007 // need to fall back to the slower path. | 1049 // need to fall back to the slower path. |
| 1008 // | 1050 // |
| 1009 // However: each NaCl process will consume 2-3 entries as it starts up, this | 1051 // However: each NaCl process will consume 2-3 entries as it starts up, this |
| 1010 // means that eviction will not happen unless you start up 33+ NaCl processes | 1052 // means that eviction will not happen unless you start up 33+ NaCl processes |
| 1011 // at the same time, and this still requires worst-case timing. As a | 1053 // at the same time, and this still requires worst-case timing. As a |
| 1012 // practical matter, no entries should be evicted prematurely. | 1054 // practical matter, no entries should be evicted prematurely. |
| 1013 // The cache itself should take ~ (150 characters * 2 bytes/char + ~60 bytes | 1055 // The cache itself should take ~ (150 characters * 2 bytes/char + ~60 bytes |
| 1014 // data structure overhead) * 100 = 35k when full, so making it bigger should | 1056 // data structure overhead) * 100 = 35k when full, so making it bigger should |
| 1015 // not be a problem, if needed. | 1057 // not be a problem, if needed. |
| 1016 // | 1058 // |
| 1017 // Each NaCl process will consume 2-3 entries because the manifest and main | 1059 // Each NaCl process will consume 2-3 entries because the manifest and main |
| 1018 // nexe are currently not resolved. Shared libraries will be resolved. They | 1060 // nexe are currently not resolved. Shared libraries will be resolved. They |
| 1019 // will be loaded sequentially, so they will only consume a single entry | 1061 // will be loaded sequentially, so they will only consume a single entry |
| 1020 // while the load is in flight. | 1062 // while the load is in flight. |
| 1021 // | |
| 1022 // TODO(ncbray): track behavior with UMA. If entries are getting evicted or | |
| 1023 // bogus keys are getting queried, this would be good to know. | |
| 1024 CHECK(!uses_nonsfi_mode_); | 1063 CHECK(!uses_nonsfi_mode_); |
| 1025 base::FilePath file_path; | 1064 base::FilePath file_path; |
| 1026 if (!NaClBrowser::GetInstance()->GetFilePath( | 1065 if (!NaClBrowser::GetInstance()->GetFilePath( |
| 1027 file_token_lo, file_token_hi, &file_path)) { | |
| 1028 NaClProcessMsg_ResolveFileToken::WriteReplyParams( | |
| 1029 reply_msg, | |
| 1030 IPC::InvalidPlatformFileForTransit(), | |
| 1031 base::FilePath()); | |
| 1032 Send(reply_msg); | |
| 1033 return; | |
| 1034 } | |
| 1035 | |
| 1036 // Open the file. | |
| 1037 if (!base::PostTaskAndReplyWithResult( | |
| 1038 content::BrowserThread::GetBlockingPool(), | |
| 1039 FROM_HERE, | |
| 1040 base::Bind(OpenNaClReadExecImpl, file_path, true /* is_executable */), | |
| 1041 base::Bind(&NaClProcessHost::FileResolved, | |
| 1042 weak_factory_.GetWeakPtr(), | |
| 1043 file_path, | |
| 1044 reply_msg))) { | |
| 1045 NaClProcessMsg_ResolveFileToken::WriteReplyParams( | |
| 1046 reply_msg, | |
| 1047 IPC::InvalidPlatformFileForTransit(), | |
| 1048 base::FilePath()); | |
| 1049 Send(reply_msg); | |
| 1050 } | |
| 1051 } | |
| 1052 | |
| 1053 void NaClProcessHost::OnResolveFileTokenAsync(uint64 file_token_lo, | |
| 1054 uint64 file_token_hi) { | |
| 1055 // See the comment at OnResolveFileToken() for details of the file path cache | |
| 1056 // behavior. | |
| 1057 CHECK(!uses_nonsfi_mode_); | |
| 1058 base::FilePath file_path; | |
| 1059 if (!NaClBrowser::GetInstance()->GetFilePath( | |
| 1060 file_token_lo, file_token_hi, &file_path)) { | 1066 file_token_lo, file_token_hi, &file_path)) { |
| 1061 Send(new NaClProcessMsg_ResolveFileTokenAsyncReply( | 1067 Send(new NaClProcessMsg_ResolveFileTokenAsyncReply( |
| 1062 file_token_lo, | 1068 file_token_lo, |
| 1063 file_token_hi, | 1069 file_token_hi, |
| 1064 IPC::PlatformFileForTransit(), | 1070 IPC::PlatformFileForTransit(), |
| 1065 base::FilePath())); | 1071 base::FilePath())); |
| 1066 return; | 1072 return; |
| 1067 } | 1073 } |
| 1068 | 1074 |
| 1069 // Open the file. | 1075 // Open the file. |
| 1070 if (!base::PostTaskAndReplyWithResult( | 1076 if (!base::PostTaskAndReplyWithResult( |
| 1071 content::BrowserThread::GetBlockingPool(), | 1077 content::BrowserThread::GetBlockingPool(), |
| 1072 FROM_HERE, | 1078 FROM_HERE, |
| 1073 base::Bind(OpenNaClReadExecImpl, file_path, true /* is_executable */), | 1079 base::Bind(OpenNaClReadExecImpl, file_path, true /* is_executable */), |
| 1074 base::Bind(&NaClProcessHost::FileResolvedAsync, | 1080 base::Bind(&NaClProcessHost::FileResolvedAsync, |
| 1075 weak_factory_.GetWeakPtr(), | 1081 weak_factory_.GetWeakPtr(), |
| 1076 file_token_lo, | 1082 file_token_lo, |
| 1077 file_token_hi, | 1083 file_token_hi, |
| 1078 file_path))) { | 1084 file_path))) { |
| 1079 Send(new NaClProcessMsg_ResolveFileTokenAsyncReply( | 1085 Send(new NaClProcessMsg_ResolveFileTokenAsyncReply( |
| 1080 file_token_lo, | 1086 file_token_lo, |
| 1081 file_token_hi, | 1087 file_token_hi, |
| 1082 IPC::PlatformFileForTransit(), | 1088 IPC::PlatformFileForTransit(), |
| 1083 base::FilePath())); | 1089 base::FilePath())); |
| 1084 } | 1090 } |
| 1085 } | 1091 } |
| 1086 | 1092 |
| 1087 void NaClProcessHost::FileResolved( | |
| 1088 const base::FilePath& file_path, | |
| 1089 IPC::Message* reply_msg, | |
| 1090 base::File file) { | |
| 1091 if (file.IsValid()) { | |
| 1092 IPC::PlatformFileForTransit handle = IPC::TakeFileHandleForProcess( | |
| 1093 file.Pass(), | |
| 1094 process_->GetData().handle); | |
| 1095 NaClProcessMsg_ResolveFileToken::WriteReplyParams( | |
| 1096 reply_msg, | |
| 1097 handle, | |
| 1098 file_path); | |
| 1099 } else { | |
| 1100 NaClProcessMsg_ResolveFileToken::WriteReplyParams( | |
| 1101 reply_msg, | |
| 1102 IPC::InvalidPlatformFileForTransit(), | |
| 1103 base::FilePath()); | |
| 1104 } | |
| 1105 Send(reply_msg); | |
| 1106 } | |
| 1107 | |
| 1108 void NaClProcessHost::FileResolvedAsync( | 1093 void NaClProcessHost::FileResolvedAsync( |
| 1109 uint64_t file_token_lo, | 1094 uint64_t file_token_lo, |
| 1110 uint64_t file_token_hi, | 1095 uint64_t file_token_hi, |
| 1111 const base::FilePath& file_path, | 1096 const base::FilePath& file_path, |
| 1112 base::File file) { | 1097 base::File file) { |
| 1113 base::FilePath out_file_path; | 1098 base::FilePath out_file_path; |
| 1114 IPC::PlatformFileForTransit out_handle; | 1099 IPC::PlatformFileForTransit out_handle; |
| 1115 if (file.IsValid()) { | 1100 if (file.IsValid()) { |
| 1116 out_file_path = file_path; | 1101 out_file_path = file_path; |
| 1117 out_handle = IPC::TakeFileHandleForProcess( | 1102 out_handle = IPC::TakeFileHandleForProcess( |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1194 process_handle.Take(), info, | 1179 process_handle.Take(), info, |
| 1195 base::MessageLoopProxy::current(), | 1180 base::MessageLoopProxy::current(), |
| 1196 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1181 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
| 1197 weak_factory_.GetWeakPtr())); | 1182 weak_factory_.GetWeakPtr())); |
| 1198 return true; | 1183 return true; |
| 1199 } | 1184 } |
| 1200 } | 1185 } |
| 1201 #endif | 1186 #endif |
| 1202 | 1187 |
| 1203 } // namespace nacl | 1188 } // namespace nacl |
| OLD | NEW |