diff options
author | mseaborn <mseaborn@chromium.org> | 2015-01-21 18:41:44 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-22 02:42:31 +0000 |
commit | 9f45f6309ae6cbeaf1b08844f32c4579df3acf18 (patch) | |
tree | 33a3cf2f867d7eecf1b8addd4b156433f73fdb7c /components/nacl/renderer/ppb_nacl_private_impl.cc | |
parent | aa86822199fde1867c78cf221fb81a1e8170ae22 (diff) | |
download | chromium_src-9f45f6309ae6cbeaf1b08844f32c4579df3acf18.zip chromium_src-9f45f6309ae6cbeaf1b08844f32c4579df3acf18.tar.gz chromium_src-9f45f6309ae6cbeaf1b08844f32c4579df3acf18.tar.bz2 |
NaCl: Merge three global PP_Instance mappings into one
components/nacl/renderer/ had three mappings from PP_Instance IDs:
* mapping to NexeLoadManager
* mapping to JsonManifest
* mapping to InstanceInfo
Merging these into one will make it easier to add more per-PP_Instance
state in the future.
This also makes the lifetime of the objects mapped from PP_Instances
clearer. This should fix a leak of InstanceInfo if untrusted code
never calls the StartPpapiProxy IPC (though the IPC::ChannelHandle in
it will still leak since this isn't owned).
BUG=428030
TEST=NaCl tests in browser_tests
Review URL: https://codereview.chromium.org/856583003
Cr-Commit-Position: refs/heads/master@{#312540}
Diffstat (limited to 'components/nacl/renderer/ppb_nacl_private_impl.cc')
-rw-r--r-- | components/nacl/renderer/ppb_nacl_private_impl.cc | 126 |
1 files changed, 85 insertions, 41 deletions
diff --git a/components/nacl/renderer/ppb_nacl_private_impl.cc b/components/nacl/renderer/ppb_nacl_private_impl.cc index 86889b7..fd8dcc1 100644 --- a/components/nacl/renderer/ppb_nacl_private_impl.cc +++ b/components/nacl/renderer/ppb_nacl_private_impl.cc @@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" +#include "base/containers/scoped_ptr_hash_map.h" #include "base/cpu.h" #include "base/files/file.h" #include "base/lazy_instance.h" @@ -88,6 +89,8 @@ bool InitializePnaclResourceHost() { return true; } +// This contains state that is produced by LaunchSelLdr() and consumed +// by StartPpapiProxy(). struct InstanceInfo { InstanceInfo() : plugin_pid(base::kNullProcessId), plugin_child_id(0) {} GURL url; @@ -97,10 +100,39 @@ struct InstanceInfo { IPC::ChannelHandle channel_handle; }; -typedef std::map<PP_Instance, InstanceInfo> InstanceInfoMap; +class NaClPluginInstance { + public: + NaClPluginInstance(PP_Instance instance): nexe_load_manager(instance) {} + + NexeLoadManager nexe_load_manager; + scoped_ptr<JsonManifest> json_manifest; + scoped_ptr<InstanceInfo> instance_info; +}; + +typedef base::ScopedPtrHashMap<PP_Instance, NaClPluginInstance> InstanceMap; +base::LazyInstance<InstanceMap> g_instance_map = LAZY_INSTANCE_INITIALIZER; + +NaClPluginInstance* GetNaClPluginInstance(PP_Instance instance) { + InstanceMap& map = g_instance_map.Get(); + InstanceMap::iterator iter = map.find(instance); + if (iter == map.end()) + return NULL; + return iter->second; +} -base::LazyInstance<InstanceInfoMap> g_instance_info = - LAZY_INSTANCE_INITIALIZER; +NexeLoadManager* GetNexeLoadManager(PP_Instance instance) { + NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); + if (!nacl_plugin_instance) + return NULL; + return &nacl_plugin_instance->nexe_load_manager; +} + +JsonManifest* GetJsonManifest(PP_Instance instance) { + NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); + if (!nacl_plugin_instance) + return NULL; + return nacl_plugin_instance->json_manifest.get(); +} static const PP_NaClFileInfo kInvalidNaClFileInfo = { PP_kInvalidFileHandle, @@ -169,7 +201,7 @@ class ManifestServiceProxy : public ManifestServiceChannel::Delegate { void StartupInitializationComplete() override { if (StartPpapiProxy(pp_instance_) == PP_TRUE) { JsonManifest* manifest = GetJsonManifest(pp_instance_); - NexeLoadManager* load_manager = NexeLoadManager::Get(pp_instance_); + NexeLoadManager* load_manager = GetNexeLoadManager(pp_instance_); if (load_manager && manifest) { std::string full_url; PP_PNaClOptions pnacl_options; @@ -376,7 +408,7 @@ void LaunchSelLdr(PP_Instance instance, return; } - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); if (!load_manager) { PostPPCompletionCallback(callback, PP_ERROR_FAILED); @@ -403,8 +435,10 @@ void LaunchSelLdr(PP_Instance instance, instance_info.plugin_child_id = launch_result.plugin_child_id; // Don't save instance_info if channel handle is invalid. - if (IsValidChannelHandle(instance_info.channel_handle)) - g_instance_info.Get()[instance] = instance_info; + if (IsValidChannelHandle(instance_info.channel_handle)) { + NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); + nacl_plugin_instance->instance_info.reset(new InstanceInfo(instance_info)); + } *(static_cast<NaClHandle*>(imc_handle)) = ToNativeHandle(result_socket); @@ -452,7 +486,7 @@ void LaunchSelLdr(PP_Instance instance, } PP_Bool StartPpapiProxy(PP_Instance instance) { - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); if (!load_manager) return PP_FALSE; @@ -464,21 +498,20 @@ PP_Bool StartPpapiProxy(PP_Instance instance) { return PP_FALSE; } - InstanceInfoMap& map = g_instance_info.Get(); - InstanceInfoMap::iterator it = map.find(instance); - if (it == map.end()) { + NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); + if (!nacl_plugin_instance->instance_info) { DLOG(ERROR) << "Could not find instance ID"; return PP_FALSE; } - InstanceInfo instance_info = it->second; - map.erase(it); + scoped_ptr<InstanceInfo> instance_info = + nacl_plugin_instance->instance_info.Pass(); PP_ExternalPluginResult result = plugin_instance->SwitchToOutOfProcessProxy( - base::FilePath().AppendASCII(instance_info.url.spec()), - instance_info.permissions, - instance_info.channel_handle, - instance_info.plugin_pid, - instance_info.plugin_child_id); + base::FilePath().AppendASCII(instance_info->url.spec()), + instance_info->permissions, + instance_info->channel_handle, + instance_info->plugin_pid, + instance_info->plugin_child_id); if (result == PP_EXTERNAL_PLUGIN_OK) { // Log the amound of time that has passed between the trusted plugin being @@ -644,7 +677,7 @@ void ReportTranslationFinished(PP_Instance instance, compile_time_us); HistogramSizeKB("NaCl.Perf.Size.Pexe", pexe_size / 1024); - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); if (load_manager) { base::TimeDelta total_time = base::Time::Now() - load_manager->pnacl_start_time(); @@ -672,7 +705,7 @@ PP_FileHandle OpenNaClExecutable(PP_Instance instance, if (!gurl.SchemeIs("chrome-extension")) return PP_kInvalidFileHandle; - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); if (!load_manager) return PP_kInvalidFileHandle; @@ -729,7 +762,7 @@ void DispatchEvent(PP_Instance instance, void ReportLoadSuccess(PP_Instance instance, uint64_t loaded_bytes, uint64_t total_bytes) { - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); if (load_manager) { load_manager->ReportLoadSuccess(load_manager->program_url(), loaded_bytes, @@ -740,18 +773,29 @@ void ReportLoadSuccess(PP_Instance instance, void ReportLoadError(PP_Instance instance, PP_NaClError error, const char* error_message) { - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); if (load_manager) load_manager->ReportLoadError(error, error_message); } void InstanceCreated(PP_Instance instance) { - NexeLoadManager::Create(instance); + InstanceMap& map = g_instance_map.Get(); + CHECK(map.find(instance) == map.end()); // Sanity check. + scoped_ptr<NaClPluginInstance> new_instance(new NaClPluginInstance(instance)); + map.add(instance, new_instance.Pass()); } void InstanceDestroyed(PP_Instance instance) { - DeleteJsonManifest(instance); - NexeLoadManager::Delete(instance); + InstanceMap& map = g_instance_map.Get(); + InstanceMap::iterator iter = map.find(instance); + CHECK(iter != map.end()); + // The erase may call NexeLoadManager's destructor prior to removing it from + // the map. In that case, it is possible for the trusted Plugin to re-enter + // the NexeLoadManager (e.g., by calling ReportLoadError). Passing out the + // NexeLoadManager to a local scoped_ptr just ensures that its entry is gone + // from the map prior to the destructor being invoked. + scoped_ptr<NaClPluginInstance> temp(map.take(instance)); + map.erase(iter); } PP_Bool NaClDebugEnabledForURL(const char* alleged_nmf_url) { @@ -775,7 +819,7 @@ void InitializePlugin(PP_Instance instance, uint32_t argc, const char* argn[], const char* argv[]) { - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); if (load_manager) load_manager->InitializePlugin(argc, argn, argv); @@ -790,7 +834,7 @@ bool CreateJsonManifest(PP_Instance instance, void RequestNaClManifest(PP_Instance instance, PP_CompletionCallback callback) { - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); if (!load_manager) { ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( @@ -837,7 +881,7 @@ void RequestNaClManifest(PP_Instance instance, } PP_Var GetManifestBaseURL(PP_Instance instance) { - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); if (!load_manager) return PP_MakeUndefined(); @@ -848,13 +892,13 @@ PP_Var GetManifestBaseURL(PP_Instance instance) { } void ProcessNaClManifest(PP_Instance instance, const char* program_url) { - nacl::NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); if (load_manager) load_manager->ProcessNaClManifest(program_url); } PP_Bool DevInterfacesEnabled(PP_Instance instance) { - nacl::NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); if (load_manager) return PP_FromBool(load_manager->DevInterfacesEnabled()); return PP_FALSE; @@ -868,7 +912,7 @@ void DownloadManifestToBufferCompletion(PP_Instance instance, void DownloadManifestToBuffer(PP_Instance instance, struct PP_CompletionCallback callback) { - nacl::NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); content::PepperPluginInstance* plugin_instance = content::PepperPluginInstance::Get(instance); @@ -904,7 +948,7 @@ void DownloadManifestToBufferCompletion(PP_Instance instance, HistogramTimeSmall("NaCl.Perf.StartupTime.ManifestDownload", download_time.InMilliseconds()); - nacl::NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); if (!load_manager) { callback.func(callback.user_data, PP_ERROR_ABORTED); return; @@ -951,7 +995,7 @@ bool CreateJsonManifest(PP_Instance instance, HistogramSizeKB("NaCl.Perf.Size.Manifest", static_cast<int32_t>(manifest_data.length() / 1024)); - nacl::NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); if (!load_manager) return false; @@ -969,7 +1013,7 @@ bool CreateJsonManifest(PP_Instance instance, PP_ToBool(NaClDebugEnabledForURL(manifest_url.c_str())))); JsonManifest::ErrorInfo error_info; if (j->Init(manifest_data.c_str(), &error_info)) { - AddJsonManifest(instance, j.Pass()); + GetNaClPluginInstance(instance)->json_manifest.reset(j.release()); return true; } load_manager->ReportLoadError(error_info.error, error_info.string); @@ -980,7 +1024,7 @@ PP_Bool ManifestGetProgramURL(PP_Instance instance, PP_Var* pp_full_url, PP_PNaClOptions* pnacl_options, PP_Bool* pp_uses_nonsfi_mode) { - nacl::NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); JsonManifest* manifest = GetJsonManifest(instance); if (manifest == NULL) @@ -1013,7 +1057,7 @@ bool ManifestResolveKey(PP_Instance instance, // We can only resolve keys in the files/ namespace. const std::string kFilesPrefix = "files/"; if (key.find(kFilesPrefix) == std::string::npos) { - nacl::NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance); if (load_manager) load_manager->ReportLoadError(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, "key did not start with files/"); @@ -1036,7 +1080,7 @@ PP_Bool GetPNaClResourceInfo(PP_Instance instance, PP_Var* llc_tool_name, PP_Var* ld_tool_name) { static const char kFilename[] = "chrome://pnacl-translator/pnacl.json"; - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); if (!load_manager) return PP_FALSE; @@ -1249,7 +1293,7 @@ void DownloadNexeCompletion(const DownloadNexeRequest& request, base::TimeDelta download_time = base::Time::Now() - request.start_time; - NexeLoadManager* load_manager = NexeLoadManager::Get(request.instance); + NexeLoadManager* load_manager = GetNexeLoadManager(request.instance); if (load_manager) { load_manager->NexeFileDidOpen(pp_error, target_file, @@ -1291,7 +1335,7 @@ void DownloadFile(PP_Instance instance, DCHECK(ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()-> BelongsToCurrentThread()); - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); if (!load_manager) { base::MessageLoop::current()->PostTask( @@ -1391,7 +1435,7 @@ void ReportSelLdrStatus(PP_Instance instance, int32_t load_status, int32_t max_status) { HistogramEnumerate("NaCl.LoadStatus.SelLdr", load_status, max_status); - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); DCHECK(load_manager); if (!load_manager) return; @@ -1446,7 +1490,7 @@ void OpenManifestEntry(PP_Instance instance, } void SetPNaClStartTime(PP_Instance instance) { - NexeLoadManager* load_manager = NexeLoadManager::Get(instance); + NexeLoadManager* load_manager = GetNexeLoadManager(instance); if (load_manager) load_manager->set_pnacl_start_time(base::Time::Now()); } |