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

Side by Side Diff: components/nacl/browser/nacl_process_host.cc

Issue 572973002: NaCl: Simpler validation for main nexe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 6 years 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
« no previous file with comments | « components/nacl/browser/nacl_process_host.h ('k') | components/nacl/common/nacl_messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 reinterpret_cast<nacl::FileDescriptor>(channel)); 219 reinterpret_cast<nacl::FileDescriptor>(channel));
220 #else 220 #else
221 nacl::FileDescriptor channel; 221 nacl::FileDescriptor channel;
222 channel.fd = sourceh; 222 channel.fd = sourceh;
223 channel.auto_close = close_source; 223 channel.auto_close = close_source;
224 handles_for_sel_ldr->push_back(channel); 224 handles_for_sel_ldr->push_back(channel);
225 #endif 225 #endif
226 return true; 226 return true;
227 } 227 }
228 228
229 void CloseFile(base::File file) {
230 // The base::File destructor will close the file for us.
231 }
232
229 } // namespace 233 } // namespace
230 234
231 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = 235 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ =
232 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds; 236 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds;
233 237
234 NaClProcessHost::NaClProcessHost(const GURL& manifest_url, 238 NaClProcessHost::NaClProcessHost(const GURL& manifest_url,
235 base::File nexe_file, 239 base::File nexe_file,
236 const NaClFileToken& nexe_token, 240 const NaClFileToken& nexe_token,
237 ppapi::PpapiPermissions permissions, 241 ppapi::PpapiPermissions permissions,
238 int render_view_id, 242 int render_view_id,
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, 625 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated,
622 OnPpapiChannelsCreated) 626 OnPpapiChannelsCreated)
623 IPC_MESSAGE_UNHANDLED(handled = false) 627 IPC_MESSAGE_UNHANDLED(handled = false)
624 IPC_END_MESSAGE_MAP() 628 IPC_END_MESSAGE_MAP()
625 } else { 629 } else {
626 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) 630 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg)
627 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, 631 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate,
628 OnQueryKnownToValidate) 632 OnQueryKnownToValidate)
629 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, 633 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate,
630 OnSetKnownToValidate) 634 OnSetKnownToValidate)
631 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_ResolveFileToken, 635 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileToken,
632 OnResolveFileToken) 636 OnResolveFileToken)
633 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileTokenAsync,
634 OnResolveFileTokenAsync)
635 637
636 #if defined(OS_WIN) 638 #if defined(OS_WIN)
637 IPC_MESSAGE_HANDLER_DELAY_REPLY( 639 IPC_MESSAGE_HANDLER_DELAY_REPLY(
638 NaClProcessMsg_AttachDebugExceptionHandler, 640 NaClProcessMsg_AttachDebugExceptionHandler,
639 OnAttachDebugExceptionHandler) 641 OnAttachDebugExceptionHandler)
640 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected, 642 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected,
641 OnDebugStubPortSelected) 643 OnDebugStubPortSelected)
642 #endif 644 #endif
643 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, 645 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated,
644 OnPpapiChannelsCreated) 646 OnPpapiChannelsCreated)
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 // not created. 813 // not created.
812 DCHECK(!socket_for_sel_ldr_.IsValid()); 814 DCHECK(!socket_for_sel_ldr_.IsValid());
813 #endif 815 #endif
814 } else { 816 } else {
815 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); 817 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled();
816 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); 818 params.validation_cache_key = nacl_browser->GetValidationCacheKey();
817 params.version = NaClBrowser::GetDelegate()->GetVersionString(); 819 params.version = NaClBrowser::GetDelegate()->GetVersionString();
818 params.enable_debug_stub = enable_debug_stub_ && 820 params.enable_debug_stub = enable_debug_stub_ &&
819 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); 821 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_);
820 822
821 // TODO(teravest): Resolve the file tokens right now instead of making the
822 // loader send IPC to resolve them later.
823 params.nexe_token_lo = nexe_token_.lo;
824 params.nexe_token_hi = nexe_token_.hi;
825
826 const ChildProcessData& data = process_->GetData(); 823 const ChildProcessData& data = process_->GetData();
827 if (!ShareHandleToSelLdr(data.handle, 824 if (!ShareHandleToSelLdr(data.handle,
828 socket_for_sel_ldr_.TakePlatformFile(), 825 socket_for_sel_ldr_.TakePlatformFile(),
829 true, 826 true,
830 &params.handles)) { 827 &params.handles)) {
831 return false; 828 return false;
832 } 829 }
833 830
834 const base::File& irt_file = nacl_browser->IrtFile(); 831 const base::File& irt_file = nacl_browser->IrtFile();
835 CHECK(irt_file.IsValid()); 832 CHECK(irt_file.IsValid());
(...skipping 30 matching lines...) Expand all
866 if (params.enable_debug_stub) { 863 if (params.enable_debug_stub) {
867 net::SocketDescriptor server_bound_socket = GetDebugStubSocketHandle(); 864 net::SocketDescriptor server_bound_socket = GetDebugStubSocketHandle();
868 if (server_bound_socket != net::kInvalidSocket) { 865 if (server_bound_socket != net::kInvalidSocket) {
869 params.debug_stub_server_bound_socket = 866 params.debug_stub_server_bound_socket =
870 FileDescriptor(server_bound_socket, true); 867 FileDescriptor(server_bound_socket, true);
871 } 868 }
872 } 869 }
873 #endif 870 #endif
874 } 871 }
875 872
876 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(),
877 process_->GetData().handle);
878 if (!crash_info_shmem_.ShareToProcess(process_->GetData().handle, 873 if (!crash_info_shmem_.ShareToProcess(process_->GetData().handle,
879 &params.crash_info_shmem_handle)) { 874 &params.crash_info_shmem_handle)) {
880 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; 875 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer";
881 return false; 876 return false;
882 } 877 }
883 878
879 base::FilePath file_path;
880 // Don't retrieve the file path when using nonsfi mode; there's no validation
881 // caching in that case, so it's unnecessary work, and would expose the file
882 // path to the plugin.
883 if (!uses_nonsfi_mode_ &&
884 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);
884 process_->Send(new NaClProcessMsg_Start(params)); 906 process_->Send(new NaClProcessMsg_Start(params));
885 return true; 907 return true;
886 } 908 }
887 909
910 void NaClProcessHost::StartNaClFileResolved(
911 NaClStartParams params,
912 const base::FilePath& file_path,
913 base::File checked_nexe_file) {
914 if (checked_nexe_file.IsValid()) {
915 // Release the file received from the renderer. This has to be done on a
916 // thread where IO is permitted, though.
917 content::BrowserThread::GetBlockingPool()->PostTask(
918 FROM_HERE,
919 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass())));
920 params.nexe_file_path_metadata = file_path;
921 params.nexe_file = IPC::TakeFileHandleForProcess(
922 checked_nexe_file.Pass(), process_->GetData().handle);
923 } else {
924 params.nexe_file = IPC::TakeFileHandleForProcess(
925 nexe_file_.Pass(), process_->GetData().handle);
926 }
927 process_->Send(new NaClProcessMsg_Start(params));
928 }
929
888 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is 930 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is
889 // received. 931 // received.
890 void NaClProcessHost::OnPpapiChannelsCreated( 932 void NaClProcessHost::OnPpapiChannelsCreated(
891 const IPC::ChannelHandle& browser_channel_handle, 933 const IPC::ChannelHandle& browser_channel_handle,
892 const IPC::ChannelHandle& ppapi_renderer_channel_handle, 934 const IPC::ChannelHandle& ppapi_renderer_channel_handle,
893 const IPC::ChannelHandle& trusted_renderer_channel_handle, 935 const IPC::ChannelHandle& trusted_renderer_channel_handle,
894 const IPC::ChannelHandle& manifest_service_channel_handle) { 936 const IPC::ChannelHandle& manifest_service_channel_handle) {
895 if (!enable_ppapi_proxy()) { 937 if (!enable_ppapi_proxy()) {
896 ReplyToRenderer(IPC::ChannelHandle(), 938 ReplyToRenderer(IPC::ChannelHandle(),
897 trusted_renderer_channel_handle, 939 trusted_renderer_channel_handle,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); 1023 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_);
982 } 1024 }
983 1025
984 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { 1026 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) {
985 CHECK(!uses_nonsfi_mode_); 1027 CHECK(!uses_nonsfi_mode_);
986 NaClBrowser::GetInstance()->SetKnownToValidate( 1028 NaClBrowser::GetInstance()->SetKnownToValidate(
987 signature, off_the_record_); 1029 signature, off_the_record_);
988 } 1030 }
989 1031
990 void NaClProcessHost::OnResolveFileToken(uint64 file_token_lo, 1032 void NaClProcessHost::OnResolveFileToken(uint64 file_token_lo,
991 uint64 file_token_hi, 1033 uint64 file_token_hi) {
992 IPC::Message* reply_msg) {
993 // Was the file registered? 1034 // Was the file registered?
994 // 1035 //
995 // Note that the file path cache is of bounded size, and old entries can get 1036 // Note that the file path cache is of bounded size, and old entries can get
996 // evicted. If a large number of NaCl modules are being launched at once, 1037 // evicted. If a large number of NaCl modules are being launched at once,
997 // resolving the file_token may fail because the path cache was thrashed 1038 // resolving the file_token may fail because the path cache was thrashed
998 // while the file_token was in flight. In this case the query fails, and we 1039 // while the file_token was in flight. In this case the query fails, and we
999 // need to fall back to the slower path. 1040 // need to fall back to the slower path.
1000 // 1041 //
1001 // However: each NaCl process will consume 2-3 entries as it starts up, this 1042 // However: each NaCl process will consume 2-3 entries as it starts up, this
1002 // means that eviction will not happen unless you start up 33+ NaCl processes 1043 // means that eviction will not happen unless you start up 33+ NaCl processes
1003 // at the same time, and this still requires worst-case timing. As a 1044 // at the same time, and this still requires worst-case timing. As a
1004 // practical matter, no entries should be evicted prematurely. 1045 // practical matter, no entries should be evicted prematurely.
1005 // The cache itself should take ~ (150 characters * 2 bytes/char + ~60 bytes 1046 // The cache itself should take ~ (150 characters * 2 bytes/char + ~60 bytes
1006 // data structure overhead) * 100 = 35k when full, so making it bigger should 1047 // data structure overhead) * 100 = 35k when full, so making it bigger should
1007 // not be a problem, if needed. 1048 // not be a problem, if needed.
1008 // 1049 //
1009 // Each NaCl process will consume 2-3 entries because the manifest and main 1050 // Each NaCl process will consume 2-3 entries because the manifest and main
1010 // nexe are currently not resolved. Shared libraries will be resolved. They 1051 // nexe are currently not resolved. Shared libraries will be resolved. They
1011 // will be loaded sequentially, so they will only consume a single entry 1052 // will be loaded sequentially, so they will only consume a single entry
1012 // while the load is in flight. 1053 // while the load is in flight.
1013 // 1054 //
1014 // TODO(ncbray): track behavior with UMA. If entries are getting evicted or 1055 // TODO(ncbray): track behavior with UMA. If entries are getting evicted or
1015 // bogus keys are getting queried, this would be good to know. 1056 // bogus keys are getting queried, this would be good to know.
1016 CHECK(!uses_nonsfi_mode_); 1057 CHECK(!uses_nonsfi_mode_);
1017 base::FilePath file_path; 1058 base::FilePath file_path;
1018 if (!NaClBrowser::GetInstance()->GetFilePath( 1059 if (!NaClBrowser::GetInstance()->GetFilePath(
1019 file_token_lo, file_token_hi, &file_path)) { 1060 file_token_lo, file_token_hi, &file_path)) {
1020 NaClProcessMsg_ResolveFileToken::WriteReplyParams( 1061 Send(new NaClProcessMsg_ResolveFileTokenReply(
1021 reply_msg,
1022 IPC::InvalidPlatformFileForTransit(),
1023 base::FilePath());
1024 Send(reply_msg);
1025 return;
1026 }
1027
1028 // Open the file.
1029 if (!base::PostTaskAndReplyWithResult(
1030 content::BrowserThread::GetBlockingPool(),
1031 FROM_HERE,
1032 base::Bind(OpenNaClReadExecImpl, file_path, true /* is_executable */),
1033 base::Bind(&NaClProcessHost::FileResolved,
1034 weak_factory_.GetWeakPtr(),
1035 file_path,
1036 reply_msg))) {
1037 NaClProcessMsg_ResolveFileToken::WriteReplyParams(
1038 reply_msg,
1039 IPC::InvalidPlatformFileForTransit(),
1040 base::FilePath());
1041 Send(reply_msg);
1042 }
1043 }
1044
1045 void NaClProcessHost::OnResolveFileTokenAsync(uint64 file_token_lo,
1046 uint64 file_token_hi) {
1047 // See the comment at OnResolveFileToken() for details of the file path cache
1048 // behavior.
1049 CHECK(!uses_nonsfi_mode_);
1050 base::FilePath file_path;
1051 if (!NaClBrowser::GetInstance()->GetFilePath(
1052 file_token_lo, file_token_hi, &file_path)) {
1053 Send(new NaClProcessMsg_ResolveFileTokenAsyncReply(
1054 file_token_lo, 1062 file_token_lo,
1055 file_token_hi, 1063 file_token_hi,
1056 IPC::PlatformFileForTransit(), 1064 IPC::PlatformFileForTransit(),
1057 base::FilePath())); 1065 base::FilePath()));
1058 return; 1066 return;
1059 } 1067 }
1060 1068
1061 // Open the file. 1069 // Open the file.
1062 if (!base::PostTaskAndReplyWithResult( 1070 if (!base::PostTaskAndReplyWithResult(
1063 content::BrowserThread::GetBlockingPool(), 1071 content::BrowserThread::GetBlockingPool(),
1064 FROM_HERE, 1072 FROM_HERE,
1065 base::Bind(OpenNaClReadExecImpl, file_path, true /* is_executable */), 1073 base::Bind(OpenNaClReadExecImpl, file_path, true /* is_executable */),
1066 base::Bind(&NaClProcessHost::FileResolvedAsync, 1074 base::Bind(&NaClProcessHost::FileResolved,
1067 weak_factory_.GetWeakPtr(), 1075 weak_factory_.GetWeakPtr(),
1068 file_token_lo, 1076 file_token_lo,
1069 file_token_hi, 1077 file_token_hi,
1070 file_path))) { 1078 file_path))) {
1071 Send(new NaClProcessMsg_ResolveFileTokenAsyncReply( 1079 Send(new NaClProcessMsg_ResolveFileTokenReply(
1072 file_token_lo, 1080 file_token_lo,
1073 file_token_hi, 1081 file_token_hi,
1074 IPC::PlatformFileForTransit(), 1082 IPC::PlatformFileForTransit(),
1075 base::FilePath())); 1083 base::FilePath()));
1076 } 1084 }
1077 } 1085 }
1078 1086
1079 void NaClProcessHost::FileResolved( 1087 void NaClProcessHost::FileResolved(
1080 const base::FilePath& file_path,
1081 IPC::Message* reply_msg,
1082 base::File file) {
1083 if (file.IsValid()) {
1084 IPC::PlatformFileForTransit handle = IPC::TakeFileHandleForProcess(
1085 file.Pass(),
1086 process_->GetData().handle);
1087 NaClProcessMsg_ResolveFileToken::WriteReplyParams(
1088 reply_msg,
1089 handle,
1090 file_path);
1091 } else {
1092 NaClProcessMsg_ResolveFileToken::WriteReplyParams(
1093 reply_msg,
1094 IPC::InvalidPlatformFileForTransit(),
1095 base::FilePath());
1096 }
1097 Send(reply_msg);
1098 }
1099
1100 void NaClProcessHost::FileResolvedAsync(
1101 uint64_t file_token_lo, 1088 uint64_t file_token_lo,
1102 uint64_t file_token_hi, 1089 uint64_t file_token_hi,
1103 const base::FilePath& file_path, 1090 const base::FilePath& file_path,
1104 base::File file) { 1091 base::File file) {
1105 base::FilePath out_file_path; 1092 base::FilePath out_file_path;
1106 IPC::PlatformFileForTransit out_handle; 1093 IPC::PlatformFileForTransit out_handle;
1107 if (file.IsValid()) { 1094 if (file.IsValid()) {
1108 out_file_path = file_path; 1095 out_file_path = file_path;
1109 out_handle = IPC::TakeFileHandleForProcess( 1096 out_handle = IPC::TakeFileHandleForProcess(
1110 file.Pass(), 1097 file.Pass(),
1111 process_->GetData().handle); 1098 process_->GetData().handle);
1112 } else { 1099 } else {
1113 out_handle = IPC::InvalidPlatformFileForTransit(); 1100 out_handle = IPC::InvalidPlatformFileForTransit();
1114 } 1101 }
1115 Send(new NaClProcessMsg_ResolveFileTokenAsyncReply( 1102 Send(new NaClProcessMsg_ResolveFileTokenReply(
1116 file_token_lo, 1103 file_token_lo,
1117 file_token_hi, 1104 file_token_hi,
1118 out_handle, 1105 out_handle,
1119 out_file_path)); 1106 out_file_path));
1120 } 1107 }
1121 1108
1122 #if defined(OS_WIN) 1109 #if defined(OS_WIN)
1123 void NaClProcessHost::OnAttachDebugExceptionHandler(const std::string& info, 1110 void NaClProcessHost::OnAttachDebugExceptionHandler(const std::string& info,
1124 IPC::Message* reply_msg) { 1111 IPC::Message* reply_msg) {
1125 CHECK(!uses_nonsfi_mode_); 1112 CHECK(!uses_nonsfi_mode_);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 process_handle.Take(), info, 1173 process_handle.Take(), info,
1187 base::MessageLoopProxy::current(), 1174 base::MessageLoopProxy::current(),
1188 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 1175 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
1189 weak_factory_.GetWeakPtr())); 1176 weak_factory_.GetWeakPtr()));
1190 return true; 1177 return true;
1191 } 1178 }
1192 } 1179 }
1193 #endif 1180 #endif
1194 1181
1195 } // namespace nacl 1182 } // namespace nacl
OLDNEW
« no previous file with comments | « components/nacl/browser/nacl_process_host.h ('k') | components/nacl/common/nacl_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698