summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/memory_details.cc2
-rw-r--r--chrome/browser/nacl_host/nacl_broker_host.cc74
-rw-r--r--chrome/browser/nacl_host/nacl_broker_host.h46
-rw-r--r--chrome/browser/nacl_host/nacl_broker_service.cc69
-rw-r--r--chrome/browser/nacl_host/nacl_broker_service.h57
-rw-r--r--chrome/browser/nacl_process_host.cc110
-rw-r--r--chrome/browser/nacl_process_host.h13
7 files changed, 326 insertions, 45 deletions
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc
index f212698..4c7e2fb 100644
--- a/chrome/browser/memory_details.cc
+++ b/chrome/browser/memory_details.cc
@@ -209,7 +209,7 @@ void MemoryDetails::UpdateHistograms() {
case ChildProcessInfo::SANDBOX_HELPER_PROCESS:
UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
break;
- case ChildProcessInfo::NACL_PROCESS:
+ case ChildProcessInfo::NACL_LOADER_PROCESS:
UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
break;
default:
diff --git a/chrome/browser/nacl_host/nacl_broker_host.cc b/chrome/browser/nacl_host/nacl_broker_host.cc
new file mode 100644
index 0000000..8abc228
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_broker_host.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/nacl_host/nacl_broker_host.h"
+
+#include "base/command_line.h"
+#include "ipc/ipc_switches.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/nacl_host/nacl_broker_service.h"
+#include "chrome/browser/nacl_process_host.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/nacl_cmd_line.h"
+#include "chrome/common/nacl_messages.h"
+
+NaClBrokerHost::NaClBrokerHost(
+ ResourceDispatcherHost* resource_dispatcher_host)
+ : ChildProcessHost(NACL_BROKER_PROCESS, resource_dispatcher_host) {
+}
+
+NaClBrokerHost::~NaClBrokerHost() {
+}
+
+URLRequestContext* NaClBrokerHost::GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data) {
+ return NULL;
+}
+
+bool NaClBrokerHost::Init() {
+ // Create the channel that will be used for communicating with the broker.
+ if (!CreateChannel())
+ return false;
+
+ // Create the path to the nacl broker/loader executable.
+ FilePath exe_path = GetChildPath(false);
+ if (exe_path.empty())
+ return false;
+
+ FilePath nacl_path = exe_path.DirName().Append(chrome::kNaClAppName);
+ CommandLine* cmd_line = new CommandLine(nacl_path);
+ nacl::CopyNaClCommandLineArguments(cmd_line);
+
+ cmd_line->AppendSwitchWithValue(switches::kProcessType,
+ switches::kNaClBrokerProcess);
+
+ cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
+ ASCIIToWide(channel_id()));
+
+ ChildProcessHost::Launch(FilePath(), cmd_line);
+ return true;
+}
+
+void NaClBrokerHost::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(NaClBrokerHost, msg)
+ IPC_MESSAGE_HANDLER(NaClProcessMsg_BrokerReady, OnBrokerReady)
+ IPC_MESSAGE_HANDLER(NaClProcessMsg_LoaderLaunched, OnLoaderLaunched)
+ IPC_END_MESSAGE_MAP()
+}
+
+void NaClBrokerHost::OnBrokerReady() {
+ NaClBrokerService::GetInstance()->OnBrokerStarted();
+}
+
+bool NaClBrokerHost::LaunchLoader(
+ const std::wstring& loader_channel_id) {
+ return Send(new NaClProcessMsg_LaunchLoaderThroughBroker(loader_channel_id));
+}
+
+void NaClBrokerHost::OnLoaderLaunched(const std::wstring& loader_channel_id,
+ base::ProcessHandle handle) {
+ NaClBrokerService::GetInstance()->OnLoaderLaunched(loader_channel_id, handle);
+}
diff --git a/chrome/browser/nacl_host/nacl_broker_host.h b/chrome/browser/nacl_host/nacl_broker_host.h
new file mode 100644
index 0000000..f526aa1
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_broker_host.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NACL_HOST_NACL_BROKER_HOST_H_
+#define CHROME_BROWSER_NACL_HOST_NACL_BROKER_HOST_H_
+
+#include "base/basictypes.h"
+#include "base/process.h"
+#include "chrome/common/child_process_host.h"
+#include "ipc/ipc_message.h"
+
+class NaClBrokerHost : public ChildProcessHost {
+ public:
+ explicit NaClBrokerHost(ResourceDispatcherHost* resource_dispatcher_host);
+ ~NaClBrokerHost();
+
+ // This function starts the broker process. It needs to be called
+ // before loaders can be launched.
+ bool Init();
+
+ // Send a message to the broker process, causing it to launch
+ // a Native Client loader process.
+ bool LaunchLoader(const std::wstring& loader_channel_id);
+
+ private:
+ // ResourceDispatcherHost::Receiver implementation:
+ virtual URLRequestContext* GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data);
+
+ virtual bool CanShutdown() { return true; }
+
+ // Handler for NaClProcessMsg_BrokerReady message (sent by the broker process)
+ void OnBrokerReady();
+ // Handler for NaClProcessMsg_LoaderLaunched message
+ void OnLoaderLaunched(const std::wstring& loader_channel_id,
+ base::ProcessHandle handle);
+
+ // IPC::Channel::Listener
+ virtual void OnMessageReceived(const IPC::Message& msg);
+
+ DISALLOW_COPY_AND_ASSIGN(NaClBrokerHost);
+};
+
+#endif // CHROME_BROWSER_NACL_HOST_NACL_BROKER_HOST_H_
diff --git a/chrome/browser/nacl_host/nacl_broker_service.cc b/chrome/browser/nacl_host/nacl_broker_service.cc
new file mode 100644
index 0000000..ef659cd
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_broker_service.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/nacl_host/nacl_broker_service.h"
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/nacl_process_host.h"
+#include "chrome/common/chrome_switches.h"
+
+NaClBrokerService* NaClBrokerService::GetInstance() {
+ return Singleton<NaClBrokerService>::get();
+}
+
+NaClBrokerService::NaClBrokerService()
+ : broker_started_(false),
+ broker_host_(NULL),
+ resource_dispatcher_host_(NULL),
+ initialized_(false) {
+}
+
+void NaClBrokerService::Init(ResourceDispatcherHost* resource_dispatcher_host) {
+ if (initialized_) {
+ return;
+ }
+ resource_dispatcher_host_ = resource_dispatcher_host;
+ StartBroker();
+ initialized_ = true;
+}
+
+bool NaClBrokerService::StartBroker() {
+ broker_host_.reset(new NaClBrokerHost(resource_dispatcher_host_));
+ if (!broker_host_->Init()) {
+ // Initialization failed, we will not retry in the future
+ broker_host_.reset(NULL);
+ }
+ return (broker_host_ != NULL);
+}
+
+bool NaClBrokerService::LaunchLoader(NaClProcessHost* nacl_process_host,
+ const std::wstring& loader_channel_id) {
+ if (broker_started_) {
+ broker_host_->LaunchLoader(loader_channel_id);
+ } else {
+ // Add task to the list
+ pending_launches_[loader_channel_id] = nacl_process_host;
+ }
+ return true;
+}
+
+void NaClBrokerService::OnBrokerStarted() {
+ PendingLaunchesMap::iterator it;
+ for (it = pending_launches_.begin(); it != pending_launches_.end(); it++) {
+ broker_host_->LaunchLoader(it->first);
+ }
+ broker_started_ = true;
+}
+
+void NaClBrokerService::OnLoaderLaunched(const std::wstring& channel_id,
+ base::ProcessHandle handle) {
+ NaClProcessHost* client;
+ PendingLaunchesMap::iterator it = pending_launches_.find(channel_id);
+ if (pending_launches_.end() == it) {
+ NOTREACHED();
+ }
+ client = it->second;
+ client->OnProcessLaunchedByBroker(handle);
+ pending_launches_.erase(it);
+}
diff --git a/chrome/browser/nacl_host/nacl_broker_service.h b/chrome/browser/nacl_host/nacl_broker_service.h
new file mode 100644
index 0000000..75e089d
--- /dev/null
+++ b/chrome/browser/nacl_host/nacl_broker_service.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NACL_HOST_NACL_BROKER_SERVICE_H_
+#define CHROME_BROWSER_NACL_HOST_NACL_BROKER_SERVICE_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/singleton.h"
+#include "chrome/browser/nacl_host/nacl_broker_host.h"
+
+class NaClProcessHost;
+
+class NaClBrokerService {
+ public:
+ // Returns the NaClBrokerService singleton.
+ static NaClBrokerService* GetInstance();
+
+ void Init(ResourceDispatcherHost* resource_dispatcher_host);
+
+ // Can be called several times, must be called before LaunchLoader.
+ bool StartBroker();
+
+ // Send a message to the broker process, causing it to launch
+ // a Native Client loader process.
+ bool LaunchLoader(NaClProcessHost* client,
+ const std::wstring& loader_channel_id);
+
+ // Called by NaClBrokerHost to notify the service
+ // that the broker was launched.
+ void OnBrokerStarted();
+
+ // Called by NaClBrokerHost to notify the service that a loader was launched.
+ void OnLoaderLaunched(const std::wstring& channel_id,
+ base::ProcessHandle handle);
+
+ private:
+ typedef std::map<std::wstring, NaClProcessHost*>
+ PendingLaunchesMap;
+
+ friend struct DefaultSingletonTraits<NaClBrokerService>;
+
+ NaClBrokerService();
+ ~NaClBrokerService() {}
+
+ bool broker_started_;
+ scoped_ptr<NaClBrokerHost> broker_host_;
+ bool initialized_;
+ ResourceDispatcherHost* resource_dispatcher_host_;
+ PendingLaunchesMap pending_launches_;
+
+ DISALLOW_COPY_AND_ASSIGN(NaClBrokerService);
+};
+
+#endif // CHROME_BROWSER_NACL_HOST_NACL_BROKER_SERVICE_H_
diff --git a/chrome/browser/nacl_process_host.cc b/chrome/browser/nacl_process_host.cc
index f736ab7..c82b06d 100644
--- a/chrome/browser/nacl_process_host.cc
+++ b/chrome/browser/nacl_process_host.cc
@@ -10,9 +10,12 @@
#include <fcntl.h>
#endif
+#include "base/command_line.h"
+#include "chrome/browser/nacl_host/nacl_broker_service.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/logging_chrome.h"
+#include "chrome/common/nacl_cmd_line.h"
#include "chrome/common/nacl_messages.h"
#include "chrome/common/render_messages.h"
#include "ipc/ipc_switches.h"
@@ -24,11 +27,15 @@
NaClProcessHost::NaClProcessHost(
ResourceDispatcherHost *resource_dispatcher_host,
const std::wstring& url)
- : ChildProcessHost(NACL_PROCESS, resource_dispatcher_host),
+ : ChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host),
resource_dispatcher_host_(resource_dispatcher_host),
reply_msg_(NULL),
- descriptor_(0) {
+ descriptor_(0),
+ running_on_wow64_(false) {
set_name(url);
+#if defined(OS_WIN)
+ CheckIsWow64();
+#endif
}
NaClProcessHost::~NaClProcessHost() {
@@ -77,73 +84,67 @@ bool NaClProcessHost::LaunchSelLdr() {
return false;
CommandLine* cmd_line = new CommandLine(exe_path);
- if (logging::DialogsAreSuppressed())
- cmd_line->AppendSwitch(switches::kNoErrorDialogs);
-
- // Propagate the following switches to the plugin command line (along with
- // any associated values) if present in the browser command line.
- // TODO(gregoryd): check which flags of those below can be supported.
- static const char* const switch_names[] = {
- switches::kNoSandbox,
- switches::kTestSandbox,
- switches::kDisableBreakpad,
- switches::kFullMemoryCrashReport,
- switches::kEnableLogging,
- switches::kDisableLogging,
- switches::kLoggingLevel,
- switches::kEnableDCHECK,
- switches::kSilentDumpOnDCHECK,
- switches::kMemoryProfiling,
-#if defined(OS_MACOSX)
- // TODO(dspringer): remove this when NaCl x86-32 security issues are fixed
- switches::kEnableNaClOnMac,
-#endif
- };
-
- const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ nacl::CopyNaClCommandLineArguments(cmd_line);
#if defined(OS_MACOSX)
-// TODO(dspringer): NaCl is temporalrily disabled on the Mac by default, but it
-// can be enabled with the --enable-nacl cmd-line switch. Remove this check
-// when the security issues in the Mac PIC code are resolved.
- if (!browser_command_line.HasSwitch(switches::kEnableNaClOnMac))
+ // TODO(dspringer): NaCl is temporalrily disabled on the Mac by default, but
+ // it can be enabled with the --enable-nacl cmd-line switch. Remove this check
+ // when the security issues in the Mac PIC code are resolved.
+ if (!cmd_line->HasSwitch(switches::kEnableNaClOnMac))
return false;
#endif
- for (size_t i = 0; i < arraysize(switch_names); ++i) {
- if (browser_command_line.HasSwitch(switch_names[i])) {
- cmd_line->AppendSwitchWithValue(switch_names[i],
- browser_command_line.GetSwitchValueASCII(switch_names[i]));
- }
- }
-
cmd_line->AppendSwitchWithValue(switches::kProcessType,
- switches::kNaClProcess);
+ switches::kNaClLoaderProcess);
cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
ASCIIToWide(channel_id()));
- ChildProcessHost::Launch(
+ // On Windows we might need to start the broker process to launch a new loader
#if defined(OS_WIN)
- FilePath(),
+ if (running_on_wow64_) {
+ NaClBrokerService::GetInstance()->Init(resource_dispatcher_host_);
+ NaClBrokerService::GetInstance()->LaunchLoader(this,
+ ASCIIToWide(channel_id()));
+ } else
+#endif
+ ChildProcessHost::Launch(
+#if defined(OS_WIN)
+ FilePath(),
#elif defined(OS_POSIX)
- false,
- base::environment_vector(),
+ false,
+ base::environment_vector(),
#endif
- cmd_line);
+ cmd_line);
return true;
}
+void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
+ set_handle(handle);
+ OnProcessLaunched();
+}
+
+bool NaClProcessHost::DidChildCrash() {
+ if (running_on_wow64_) {
+ bool child_exited;
+ return base::DidProcessCrash(&child_exited, handle());
+ }
+ return ChildProcessHost::DidChildCrash();
+}
+
void NaClProcessHost::OnProcessLaunched() {
nacl::FileDescriptor imc_handle;
base::ProcessHandle nacl_process_handle;
#if NACL_WINDOWS
// Duplicate the IMC handle
+ // We assume the size of imc_handle has the same size as HANDLE, so the cast
+ // below is safe.
+ DCHECK(sizeof(HANDLE) == sizeof(imc_handle));
DuplicateHandle(base::GetCurrentProcessHandle(),
reinterpret_cast<HANDLE>(pair_[0]),
resource_message_filter_->handle(),
- &imc_handle,
+ reinterpret_cast<HANDLE*>(&imc_handle),
GENERIC_READ | GENERIC_WRITE,
FALSE,
DUPLICATE_CLOSE_SOURCE);
@@ -212,3 +213,24 @@ URLRequestContext* NaClProcessHost::GetRequestContext(
const ViewHostMsg_Resource_Request& request_data) {
return NULL;
}
+
+#if defined(OS_WIN)
+// TODO(gregoryd): invoke CheckIsWow64 only once, not for each NaClProcessHost
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+void NaClProcessHost::CheckIsWow64() {
+ LPFN_ISWOW64PROCESS fnIsWow64Process;
+
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
+ GetModuleHandle(TEXT("kernel32")),
+ "IsWow64Process");
+
+ if (fnIsWow64Process != NULL) {
+ BOOL bIsWow64 = FALSE;
+ if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) {
+ if (bIsWow64) {
+ running_on_wow64_ = true;
+ }
+ }
+ }
+}
+#endif
diff --git a/chrome/browser/nacl_process_host.h b/chrome/browser/nacl_process_host.h
index 8159836..ca416f6 100644
--- a/chrome/browser/nacl_process_host.h
+++ b/chrome/browser/nacl_process_host.h
@@ -33,6 +33,11 @@ class NaClProcessHost : public ChildProcessHost {
virtual void OnMessageReceived(const IPC::Message& msg);
+ void OnProcessLaunchedByBroker(base::ProcessHandle handle);
+
+ protected:
+ virtual bool DidChildCrash();
+
private:
bool LaunchSelLdr();
@@ -47,6 +52,11 @@ class NaClProcessHost : public ChildProcessHost {
virtual bool CanShutdown() { return true; }
+#if defined(OS_WIN)
+ // Check whether the browser process is running on WOW64 - Windows only
+ void CheckIsWow64();
+#endif
+
private:
ResourceDispatcherHost* resource_dispatcher_host_;
@@ -63,6 +73,9 @@ class NaClProcessHost : public ChildProcessHost {
// The NaCl specific descriptor for this process.
int descriptor_;
+ // Windows platform flag
+ bool running_on_wow64_;
+
DISALLOW_COPY_AND_ASSIGN(NaClProcessHost);
};