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 |