Chromium Code Reviews| Index: mojo/runner/child_process.cc |
| diff --git a/mojo/runner/child_process.cc b/mojo/runner/child_process.cc |
| index f5adb3030db70160cd4c0831752d760129085111..4fec5a140a03eb41004767f6a82c42507399ede8 100644 |
| --- a/mojo/runner/child_process.cc |
| +++ b/mojo/runner/child_process.cc |
| @@ -20,7 +20,6 @@ |
| #include "base/thread_task_runner_handle.h" |
| #include "base/threading/thread.h" |
| #include "base/threading/thread_checker.h" |
| -#include "base/thread_task_runner_handle.h" |
| #include "mojo/common/message_pump_mojo.h" |
| #include "mojo/edk/embedder/embedder.h" |
| #include "mojo/edk/embedder/platform_channel_pair.h" |
| @@ -32,6 +31,12 @@ |
| #include "mojo/runner/native_application_support.h" |
| #include "mojo/runner/switches.h" |
| +#if defined(OS_LINUX) && !defined(OS_ANDROID) |
| +#include "base/rand_util.h" |
| +#include "base/sys_info.h" |
| +#include "mojo/runner/linux_sandbox.h" |
| +#endif |
| + |
| namespace mojo { |
| namespace runner { |
| @@ -182,6 +187,7 @@ class ChildControllerImpl : public ChildController { |
| // To be executed on the controller thread. Creates the |ChildController|, |
| // etc. |
| static void Init(AppContext* app_context, |
| + base::NativeLibrary app_library, |
| embedder::ScopedPlatformHandle platform_channel, |
| const Blocker::Unblocker& unblocker) { |
| DCHECK(app_context); |
| @@ -190,7 +196,7 @@ class ChildControllerImpl : public ChildController { |
| DCHECK(!app_context->controller()); |
| scoped_ptr<ChildControllerImpl> impl( |
| - new ChildControllerImpl(app_context, unblocker)); |
| + new ChildControllerImpl(app_context, app_library, unblocker)); |
| ScopedMessagePipeHandle host_message_pipe(embedder::CreateChannel( |
| platform_channel.Pass(), |
| @@ -213,20 +219,14 @@ class ChildControllerImpl : public ChildController { |
| } |
| // |ChildController| methods: |
| - void StartApp(const String& app_path, |
| - bool clean_app_path, |
| - InterfaceRequest<Application> application_request, |
| + void StartApp(InterfaceRequest<Application> application_request, |
| const StartAppCallback& on_app_complete) override { |
| - DVLOG(2) << "ChildControllerImpl::StartApp(" << app_path << ", ...)"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| on_app_complete_ = on_app_complete; |
| - unblocker_.Unblock(base::Bind( |
| - &ChildControllerImpl::StartAppOnMainThread, |
| - base::FilePath::FromUTF8Unsafe(app_path), |
| - clean_app_path ? shell::NativeApplicationCleanup::DELETE |
| - : shell::NativeApplicationCleanup::DONT_DELETE, |
| - base::Passed(&application_request))); |
| + unblocker_.Unblock(base::Bind(&ChildControllerImpl::StartAppOnMainThread, |
| + base::Unretained(app_library_), |
| + base::Passed(&application_request))); |
| } |
| void ExitNow(int32_t exit_code) override { |
| @@ -236,8 +236,10 @@ class ChildControllerImpl : public ChildController { |
| private: |
| ChildControllerImpl(AppContext* app_context, |
| + base::NativeLibrary app_library, |
| const Blocker::Unblocker& unblocker) |
| : app_context_(app_context), |
| + app_library_(app_library), |
| unblocker_(unblocker), |
| channel_info_(nullptr), |
| binding_(this) { |
| @@ -252,21 +254,16 @@ class ChildControllerImpl : public ChildController { |
| } |
| static void StartAppOnMainThread( |
| - const base::FilePath& app_path, |
| - shell::NativeApplicationCleanup cleanup, |
| + base::NativeLibrary app_library, |
| InterfaceRequest<Application> application_request) { |
| - // TODO(vtl): This is copied from in_process_native_runner.cc. |
| - DVLOG(2) << "Loading/running Mojo app from " << app_path.value() |
| - << " out of process"; |
| - |
| - // We intentionally don't unload the native library as its lifetime is the |
| - // same as that of the process. |
| - base::NativeLibrary app_library = LoadNativeApplication(app_path, cleanup); |
| - RunNativeApplication(app_library, application_request.Pass()); |
| + if (!RunNativeApplication(app_library, application_request.Pass())) { |
| + LOG(ERROR) << "Failure to RunNativeApplication()"; |
| + } |
| } |
| base::ThreadChecker thread_checker_; |
| AppContext* const app_context_; |
| + base::NativeLibrary app_library_; |
| Blocker::Unblocker unblocker_; |
| StartAppCallback on_app_complete_; |
| @@ -282,6 +279,49 @@ int ChildProcessMain() { |
| DVLOG(2) << "ChildProcessMain()"; |
| const base::CommandLine& command_line = |
| *base::CommandLine::ForCurrentProcess(); |
| + |
| +#if defined(OS_LINUX) && !defined(OS_ANDROID) |
| + using sandbox::syscall_broker::BrokerFilePermission; |
| + scoped_ptr<mandoline::LinuxSandbox> sandbox; |
| +#endif |
| + base::NativeLibrary app_library = 0; |
| + if (command_line.HasSwitch(switches::kChildProcess)) { |
| + // Load the application library before we engage the sandbox. |
| + mojo::shell::NativeApplicationCleanup cleanup = |
| + command_line.HasSwitch(switches::kDeleteAfterLoad) |
| + ? mojo::shell::NativeApplicationCleanup::DELETE |
| + : mojo::shell::NativeApplicationCleanup::DONT_DELETE; |
| + app_library = mojo::runner::LoadNativeApplication( |
| + command_line.GetSwitchValuePath(switches::kChildProcess), cleanup); |
| + |
| +#if defined(OS_LINUX) && !defined(OS_ANDROID) |
| + using sandbox::syscall_broker::BrokerFilePermission; |
| + scoped_ptr<mandoline::LinuxSandbox> sandbox; |
| + if (command_line.HasSwitch(switches::kEnableSandbox)) { |
| + // Warm parts of base. |
| + base::RandUint64(); |
| + base::SysInfo::AmountOfPhysicalMemory(); |
| + base::SysInfo::MaxSharedMemorySize(); |
| + base::SysInfo::NumberOfProcessors(); |
| + |
| + // Do whatever warming that the mojo application wants. |
| + typedef void (*SandboxWarmFunction)(); |
| + SandboxWarmFunction sandbox_warm = reinterpret_cast<SandboxWarmFunction>( |
| + base::GetFunctionPointerFromNativeLibrary(app_library, |
| + "MojoSandboxWarm")); |
| + if (sandbox_warm) |
| + sandbox_warm(); |
| + |
|
jln (very slow on Chromium)
2015/07/29 20:28:04
The contract for "MojoSanboxWarm" should be:
1. D
Elliot Glaysher
2015/07/29 21:08:32
I have added the checks to LinuxSandbox::Warmup().
|
| + std::vector<BrokerFilePermission> permissions; |
| + sandbox.reset(new mandoline::LinuxSandbox(permissions)); |
| + sandbox->Warmup(); |
| + sandbox->EngageNamespaceSandbox(); |
| + sandbox->EngageSeccompSandbox(); |
| + sandbox->Seal(); |
| + } |
| +#endif |
| + } |
| + |
| embedder::ScopedPlatformHandle platform_channel = |
| embedder::PlatformChannelPair::PassClientHandleFromParentProcess( |
| command_line); |
| @@ -296,7 +336,8 @@ int ChildProcessMain() { |
| app_context.controller_runner()->PostTask( |
| FROM_HERE, |
| base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), |
| - base::Passed(&platform_channel), blocker.GetUnblocker())); |
| + base::Unretained(app_library), base::Passed(&platform_channel), |
| + blocker.GetUnblocker())); |
| // This will block, then run whatever the controller wants. |
| blocker.Block(); |