blob: 73805bce29a3eb9f1ddf573d876160f1bb9e0739 [file] [log] [blame]
// Copyright 2019 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/chrome_cleaner/engines/target/sandbox_setup.h"
#include <memory>
#include <utility>
#include "base/base_paths.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "chrome/chrome_cleaner/constants/chrome_cleaner_switches.h"
#include "chrome/chrome_cleaner/engines/target/engine_commands_impl.h"
#include "chrome/chrome_cleaner/engines/target/libraries.h"
#include "chrome/chrome_cleaner/ipc/mojo_sandbox_hooks.h"
#include "chrome/chrome_cleaner/ipc/mojo_task_runner.h"
#include "chrome/chrome_cleaner/os/early_exit.h"
namespace chrome_cleaner {
namespace {
class EngineMojoSandboxTargetHooks : public MojoSandboxTargetHooks {
public:
EngineMojoSandboxTargetHooks(scoped_refptr<EngineDelegate> engine_delegate,
MojoTaskRunner* mojo_task_runner);
~EngineMojoSandboxTargetHooks() override;
void BindEngineCommandsRequest(mojom::EngineCommandsRequest request);
// SandboxTargetHooks
ResultCode TargetDroppedPrivileges(
const base::CommandLine& command_line) override;
private:
scoped_refptr<EngineDelegate> engine_delegate_;
MojoTaskRunner* mojo_task_runner_;
base::MessageLoop message_loop_;
std::unique_ptr<EngineCommandsImpl> engine_commands_impl_;
DISALLOW_COPY_AND_ASSIGN(EngineMojoSandboxTargetHooks);
};
EngineMojoSandboxTargetHooks::EngineMojoSandboxTargetHooks(
scoped_refptr<EngineDelegate> engine_delegate,
MojoTaskRunner* mojo_task_runner)
: engine_delegate_(engine_delegate), mojo_task_runner_(mojo_task_runner) {}
EngineMojoSandboxTargetHooks::~EngineMojoSandboxTargetHooks() {
mojo_task_runner_->PostTask(
FROM_HERE, base::BindOnce(
[](std::unique_ptr<EngineCommandsImpl> commands) {
commands.reset();
},
base::Passed(&engine_commands_impl_)));
}
ResultCode EngineMojoSandboxTargetHooks::TargetDroppedPrivileges(
const base::CommandLine& command_line) {
// Connect to the Mojo message pipe from the parent process.
mojom::EngineCommandsRequest request(ExtractSandboxMessagePipe(command_line));
// This loop will run forever. Once the communication channel with the broker
// process is broken, mojo error handler will abort this process.
base::RunLoop run_loop;
mojo_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&EngineMojoSandboxTargetHooks::BindEngineCommandsRequest,
base::Unretained(this), base::Passed(&request)));
run_loop.Run();
return RESULT_CODE_SUCCESS;
}
void EngineMojoSandboxTargetHooks::BindEngineCommandsRequest(
mojom::EngineCommandsRequest request) {
// If the connection dies, the parent process has terminated unexpectedly.
// Exit immediately. The child process should be killed automatically if the
// parent dies, so this is just a fallback. The exit code is arbitrary since
// there's no parent process to collect and report it.
auto error_handler = base::BindOnce(&EarlyExit, 1);
engine_commands_impl_ = std::make_unique<EngineCommandsImpl>(
std::move(engine_delegate_), std::move(request), mojo_task_runner_,
std::move(error_handler));
}
} // namespace
ResultCode RunEngineSandboxTarget(
scoped_refptr<EngineDelegate> engine_delegate,
const base::CommandLine& command_line,
sandbox::TargetServices* sandbox_target_services) {
// Extract the libraries to the same directory as the executable.
base::FilePath extraction_dir;
CHECK(base::PathService::Get(base::DIR_EXE, &extraction_dir));
if (!LoadAndValidateLibraries(engine_delegate->engine(), extraction_dir)) {
NOTREACHED() << "Binary signature validation failed";
return RESULT_CODE_SIGNATURE_VERIFICATION_FAILED;
}
scoped_refptr<MojoTaskRunner> sandbox_mojo_task_runner =
MojoTaskRunner::Create();
EngineMojoSandboxTargetHooks mojo_target_hooks(
std::move(engine_delegate), sandbox_mojo_task_runner.get());
return RunSandboxTarget(command_line, sandbox_target_services,
&mojo_target_hooks);
}
} // namespace chrome_cleaner