| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/renderer/nexe_load_manager.h" | 5 #include "components/nacl/renderer/nexe_load_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/strings/string_tokenizer.h" | 13 #include "base/strings/string_tokenizer.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "components/nacl/common/nacl_host_messages.h" | |
| 16 #include "components/nacl/common/nacl_types.h" | 15 #include "components/nacl/common/nacl_types.h" |
| 17 #include "components/nacl/renderer/histogram.h" | 16 #include "components/nacl/renderer/histogram.h" |
| 18 #include "components/nacl/renderer/manifest_service_channel.h" | 17 #include "components/nacl/renderer/manifest_service_channel.h" |
| 19 #include "components/nacl/renderer/platform_info.h" | 18 #include "components/nacl/renderer/platform_info.h" |
| 20 #include "components/nacl/renderer/pnacl_translation_resource_host.h" | 19 #include "components/nacl/renderer/pnacl_translation_resource_host.h" |
| 21 #include "components/nacl/renderer/progress_event.h" | 20 #include "components/nacl/renderer/progress_event.h" |
| 22 #include "components/nacl/renderer/trusted_plugin_channel.h" | 21 #include "components/nacl/renderer/trusted_plugin_channel.h" |
| 23 #include "content/public/common/content_client.h" | 22 #include "content/public/common/content_client.h" |
| 24 #include "content/public/common/content_switches.h" | 23 #include "content/public/common/content_switches.h" |
| 25 #include "content/public/common/sandbox_init.h" | 24 #include "content/public/common/sandbox_init.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 std::string LookupAttribute(const std::map<std::string, std::string>& args, | 74 std::string LookupAttribute(const std::map<std::string, std::string>& args, |
| 76 const std::string& key) { | 75 const std::string& key) { |
| 77 std::map<std::string, std::string>::const_iterator it = args.find(key); | 76 std::map<std::string, std::string>::const_iterator it = args.find(key); |
| 78 if (it != args.end()) | 77 if (it != args.end()) |
| 79 return it->second; | 78 return it->second; |
| 80 return std::string(); | 79 return std::string(); |
| 81 } | 80 } |
| 82 | 81 |
| 83 } // namespace | 82 } // namespace |
| 84 | 83 |
| 85 NexeLoadManager::NexeLoadManager( | 84 NexeLoadManager::NexeLoadManager(PP_Instance pp_instance, mojom::NaClHost* host) |
| 86 PP_Instance pp_instance) | |
| 87 : pp_instance_(pp_instance), | 85 : pp_instance_(pp_instance), |
| 88 nacl_ready_state_(PP_NACL_READY_STATE_UNSENT), | 86 nacl_ready_state_(PP_NACL_READY_STATE_UNSENT), |
| 89 nexe_error_reported_(false), | 87 nexe_error_reported_(false), |
| 90 is_installed_(false), | 88 is_installed_(false), |
| 91 exit_status_(-1), | 89 exit_status_(-1), |
| 92 nexe_size_(0), | 90 nexe_size_(0), |
| 93 plugin_instance_(content::PepperPluginInstance::Get(pp_instance)), | 91 plugin_instance_(content::PepperPluginInstance::Get(pp_instance)), |
| 94 nonsfi_(false), | 92 nonsfi_(false), |
| 95 crash_info_shmem_handle_(base::SharedMemory::NULLHandle()), | 93 host_(host), |
| 96 weak_factory_(this) { | 94 weak_factory_(this) { |
| 97 set_exit_status(-1); | 95 set_exit_status(-1); |
| 98 SetLastError(""); | 96 SetLastError(""); |
| 99 HistogramEnumerateOsArch(GetSandboxArch()); | 97 HistogramEnumerateOsArch(GetSandboxArch()); |
| 100 if (plugin_instance_) { | 98 if (plugin_instance_) { |
| 101 plugin_base_url_ = | 99 plugin_base_url_ = |
| 102 plugin_instance_->GetContainer()->document().url(); | 100 plugin_instance_->GetContainer()->document().url(); |
| 103 } | 101 } |
| 104 } | 102 } |
| 105 | 103 |
| 106 NexeLoadManager::~NexeLoadManager() { | 104 NexeLoadManager::~NexeLoadManager() { |
| 107 if (!nexe_error_reported_) { | 105 if (!nexe_error_reported_) { |
| 108 base::TimeDelta uptime = base::Time::Now() - ready_time_; | 106 base::TimeDelta uptime = base::Time::Now() - ready_time_; |
| 109 HistogramTimeLarge("NaCl.ModuleUptime.Normal", uptime.InMilliseconds()); | 107 HistogramTimeLarge("NaCl.ModuleUptime.Normal", uptime.InMilliseconds()); |
| 110 } | 108 } |
| 111 if (base::SharedMemory::IsHandleValid(crash_info_shmem_handle_)) | |
| 112 base::SharedMemory::CloseHandle(crash_info_shmem_handle_); | |
| 113 } | 109 } |
| 114 | 110 |
| 115 void NexeLoadManager::NexeFileDidOpen(int32_t pp_error, | 111 void NexeLoadManager::NexeFileDidOpen(int32_t pp_error, |
| 116 const base::File& file, | 112 const base::File& file, |
| 117 int32_t http_status, | 113 int32_t http_status, |
| 118 int64_t nexe_bytes_read, | 114 int64_t nexe_bytes_read, |
| 119 const std::string& url, | 115 const std::string& url, |
| 120 base::TimeDelta time_since_open) { | 116 base::TimeDelta time_since_open) { |
| 121 // Check that we are on the main renderer thread. | 117 // Check that we are on the main renderer thread. |
| 122 DCHECK(content::RenderThread::Get()); | 118 DCHECK(content::RenderThread::Get()); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 | 186 |
| 191 void NexeLoadManager::ReportLoadError(PP_NaClError error, | 187 void NexeLoadManager::ReportLoadError(PP_NaClError error, |
| 192 const std::string& error_message, | 188 const std::string& error_message, |
| 193 const std::string& console_message) { | 189 const std::string& console_message) { |
| 194 // Check that we are on the main renderer thread. | 190 // Check that we are on the main renderer thread. |
| 195 DCHECK(content::RenderThread::Get()); | 191 DCHECK(content::RenderThread::Get()); |
| 196 | 192 |
| 197 if (error == PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH) { | 193 if (error == PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH) { |
| 198 // A special case: the manifest may otherwise be valid but is missing | 194 // A special case: the manifest may otherwise be valid but is missing |
| 199 // a program/file compatible with the user's sandbox. | 195 // a program/file compatible with the user's sandbox. |
| 200 IPC::Sender* sender = content::RenderThread::Get(); | 196 host_->MissingArchError(GetRoutingID(pp_instance_)); |
| 201 sender->Send( | |
| 202 new NaClHostMsg_MissingArchError(GetRoutingID(pp_instance_))); | |
| 203 } | 197 } |
| 204 set_nacl_ready_state(PP_NACL_READY_STATE_DONE); | 198 set_nacl_ready_state(PP_NACL_READY_STATE_DONE); |
| 205 nexe_error_reported_ = true; | 199 nexe_error_reported_ = true; |
| 206 | 200 |
| 207 // We must set all properties before calling DispatchEvent so that when an | 201 // We must set all properties before calling DispatchEvent so that when an |
| 208 // event handler runs, the properties reflect the current load state. | 202 // event handler runs, the properties reflect the current load state. |
| 209 std::string error_string = std::string("NaCl module load failed: ") + | 203 std::string error_string = std::string("NaCl module load failed: ") + |
| 210 std::string(error_message); | 204 std::string(error_message); |
| 211 SetLastError(error_string); | 205 SetLastError(error_string); |
| 212 | 206 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 "Nexe crashed during startup"); | 254 "Nexe crashed during startup"); |
| 261 } | 255 } |
| 262 } | 256 } |
| 263 // In all cases, try to grab the crash log. The first error | 257 // In all cases, try to grab the crash log. The first error |
| 264 // reported may have come from the start_module RPC reply indicating | 258 // reported may have come from the start_module RPC reply indicating |
| 265 // a validation error or something similar, which wouldn't grab the | 259 // a validation error or something similar, which wouldn't grab the |
| 266 // crash log. In the event that this is called twice, the second | 260 // crash log. In the event that this is called twice, the second |
| 267 // invocation will just be a no-op, since the entire crash log will | 261 // invocation will just be a no-op, since the entire crash log will |
| 268 // have been received and we'll just get an EOF indication. | 262 // have been received and we'll just get an EOF indication. |
| 269 | 263 |
| 270 base::SharedMemory shmem(crash_info_shmem_handle_, true); | 264 mojo::ScopedSharedBufferMapping mapping = |
| 271 if (shmem.Map(kNaClCrashInfoShmemSize)) { | 265 crash_info_shmem_handle_->Map(kNaClCrashInfoShmemSize); |
| 266 if (mapping) { |
| 272 uint32_t crash_log_length; | 267 uint32_t crash_log_length; |
| 273 // We cast the length value to volatile here to prevent the compiler from | 268 // We cast the length value to volatile here to prevent the compiler from |
| 274 // reordering instructions in a way that could introduce a TOCTTOU race. | 269 // reordering instructions in a way that could introduce a TOCTTOU race. |
| 275 crash_log_length = *(static_cast<volatile uint32_t*>(shmem.memory())); | 270 crash_log_length = *(static_cast<volatile uint32_t*>(mapping.get())); |
| 276 crash_log_length = std::min<uint32_t>(crash_log_length, | 271 crash_log_length = std::min<uint32_t>(crash_log_length, |
| 277 kNaClCrashInfoMaxLogSize); | 272 kNaClCrashInfoMaxLogSize); |
| 278 | 273 |
| 279 std::unique_ptr<char[]> crash_log_data(new char[kNaClCrashInfoShmemSize]); | 274 std::unique_ptr<char[]> crash_log_data(new char[kNaClCrashInfoShmemSize]); |
| 280 memcpy(crash_log_data.get(), | 275 memcpy(crash_log_data.get(), |
| 281 static_cast<char*>(shmem.memory()) + sizeof(uint32_t), | 276 static_cast<char*>(mapping.get()) + sizeof(uint32_t), |
| 282 crash_log_length); | 277 crash_log_length); |
| 283 std::string crash_log(crash_log_data.get(), crash_log_length); | 278 std::string crash_log(crash_log_data.get(), crash_log_length); |
| 284 CopyCrashLogToJsConsole(crash_log); | 279 CopyCrashLogToJsConsole(crash_log); |
| 285 } | 280 } |
| 286 } | 281 } |
| 287 | 282 |
| 288 void NexeLoadManager::set_trusted_plugin_channel( | 283 void NexeLoadManager::set_trusted_plugin_channel( |
| 289 std::unique_ptr<TrustedPluginChannel> channel) { | 284 std::unique_ptr<TrustedPluginChannel> channel) { |
| 290 trusted_plugin_channel_ = std::move(channel); | 285 trusted_plugin_channel_ = std::move(channel); |
| 291 } | 286 } |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 // to provide error handling. | 439 // to provide error handling. |
| 445 } | 440 } |
| 446 | 441 |
| 447 void NexeLoadManager::CopyCrashLogToJsConsole(const std::string& crash_log) { | 442 void NexeLoadManager::CopyCrashLogToJsConsole(const std::string& crash_log) { |
| 448 base::StringTokenizer t(crash_log, "\n"); | 443 base::StringTokenizer t(crash_log, "\n"); |
| 449 while (t.GetNext()) | 444 while (t.GetNext()) |
| 450 LogToConsole(t.token()); | 445 LogToConsole(t.token()); |
| 451 } | 446 } |
| 452 | 447 |
| 453 } // namespace nacl | 448 } // namespace nacl |
| OLD | NEW |