summaryrefslogtreecommitdiff
path: root/chromium/services/service_manager
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/services/service_manager')
-rw-r--r--chromium/services/service_manager/embedder/main.cc3
-rw-r--r--chromium/services/service_manager/embedder/main_delegate.cc3
-rw-r--r--chromium/services/service_manager/embedder/main_delegate.h5
-rw-r--r--chromium/services/service_manager/embedder/switches.cc3
-rw-r--r--chromium/services/service_manager/embedder/switches.h3
-rw-r--r--chromium/services/service_manager/public/cpp/binder_registry.h14
-rw-r--r--chromium/services/service_manager/public/cpp/connector.h13
-rw-r--r--chromium/services/service_manager/public/cpp/interface_binder.h27
-rw-r--r--chromium/services/service_manager/public/cpp/interface_provider.h35
-rw-r--r--chromium/services/service_manager/public/cpp/local_interface_provider.h15
-rw-r--r--chromium/services/service_manager/sandbox/BUILD.gn2
-rw-r--r--chromium/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc4
-rw-r--r--chromium/services/service_manager/sandbox/linux/bpf_tts_policy_linux.cc34
-rw-r--r--chromium/services/service_manager/sandbox/linux/bpf_tts_policy_linux.h27
-rw-r--r--chromium/services/service_manager/sandbox/linux/sandbox_linux.h2
-rw-r--r--chromium/services/service_manager/sandbox/linux/sandbox_seccomp_bpf_linux.cc4
-rw-r--r--chromium/services/service_manager/sandbox/sandbox_type.cc13
-rw-r--r--chromium/services/service_manager/sandbox/sandbox_type.h5
-rw-r--r--chromium/services/service_manager/sandbox/switches.cc3
-rw-r--r--chromium/services/service_manager/sandbox/switches.h2
-rw-r--r--chromium/services/service_manager/sandbox/win/sandbox_diagnostics.h1
-rw-r--r--chromium/services/service_manager/sandbox/win/sandbox_win.cc95
-rw-r--r--chromium/services/service_manager/sandbox/win/sandbox_win.h3
-rw-r--r--chromium/services/service_manager/service_instance.h1
-rw-r--r--chromium/services/service_manager/service_manager.cc5
-rw-r--r--chromium/services/service_manager/service_process_launcher.cc16
-rw-r--r--chromium/services/service_manager/service_process_launcher.h9
-rw-r--r--chromium/services/service_manager/zygote/BUILD.gn82
-rw-r--r--chromium/services/service_manager/zygote/DEPS3
-rw-r--r--chromium/services/service_manager/zygote/OWNERS7
-rw-r--r--chromium/services/service_manager/zygote/common/common_sandbox_support_linux.cc38
-rw-r--r--chromium/services/service_manager/zygote/common/common_sandbox_support_linux.h42
-rw-r--r--chromium/services/service_manager/zygote/common/send_zygote_child_ping_linux.cc20
-rw-r--r--chromium/services/service_manager/zygote/common/send_zygote_child_ping_linux.h18
-rw-r--r--chromium/services/service_manager/zygote/common/zygote_commands_linux.h54
-rw-r--r--chromium/services/service_manager/zygote/common/zygote_features.gni5
-rw-r--r--chromium/services/service_manager/zygote/common/zygote_fork_delegate_linux.h90
-rw-r--r--chromium/services/service_manager/zygote/common/zygote_handle.h49
-rw-r--r--chromium/services/service_manager/zygote/host/zygote_communication_linux.cc321
-rw-r--r--chromium/services/service_manager/zygote/host/zygote_communication_linux.h107
-rw-r--r--chromium/services/service_manager/zygote/host/zygote_handle_linux.cc44
-rw-r--r--chromium/services/service_manager/zygote/host/zygote_host_impl_linux.cc292
-rw-r--r--chromium/services/service_manager/zygote/host/zygote_host_impl_linux.h75
-rw-r--r--chromium/services/service_manager/zygote/zygote_host_linux.h42
-rw-r--r--chromium/services/service_manager/zygote/zygote_linux.cc659
-rw-r--r--chromium/services/service_manager/zygote/zygote_linux.h152
-rw-r--r--chromium/services/service_manager/zygote/zygote_main.h25
-rw-r--r--chromium/services/service_manager/zygote/zygote_main_linux.cc245
48 files changed, 213 insertions, 2504 deletions
diff --git a/chromium/services/service_manager/embedder/main.cc b/chromium/services/service_manager/embedder/main.cc
index f9c275cdd78..d277d1eea17 100644
--- a/chromium/services/service_manager/embedder/main.cc
+++ b/chromium/services/service_manager/embedder/main.cc
@@ -361,8 +361,7 @@ int Main(const MainParams& params) {
mojo_config.is_broker_process = true;
}
mojo_config.max_message_num_bytes = kMaximumMojoMessageSize;
- delegate->OverrideMojoConfiguration(&mojo_config);
- mojo::core::Init(mojo_config);
+ delegate->InitializeMojo(&mojo_config);
ui::RegisterPathProvider();
diff --git a/chromium/services/service_manager/embedder/main_delegate.cc b/chromium/services/service_manager/embedder/main_delegate.cc
index 439504e5012..65dec35a7a6 100644
--- a/chromium/services/service_manager/embedder/main_delegate.cc
+++ b/chromium/services/service_manager/embedder/main_delegate.cc
@@ -24,8 +24,7 @@ ProcessType MainDelegate::OverrideProcessType() {
return ProcessType::kDefault;
}
-void MainDelegate::OverrideMojoConfiguration(
- mojo::core::Configuration* config) {}
+void MainDelegate::InitializeMojo(mojo::core::Configuration* config) {}
std::vector<Manifest> MainDelegate::GetServiceManifests() {
return std::vector<Manifest>();
diff --git a/chromium/services/service_manager/embedder/main_delegate.h b/chromium/services/service_manager/embedder/main_delegate.h
index 70f9a3ed232..abced50cb03 100644
--- a/chromium/services/service_manager/embedder/main_delegate.h
+++ b/chromium/services/service_manager/embedder/main_delegate.h
@@ -71,8 +71,9 @@ class COMPONENT_EXPORT(SERVICE_MANAGER_EMBEDDER) MainDelegate {
// return |ProcessType::kDefault| to avoid overriding.
virtual ProcessType OverrideProcessType();
- // Allows the embedder to override the process-wide Mojop configuration.
- virtual void OverrideMojoConfiguration(mojo::core::Configuration* config);
+ // Allows the embedder to override the process-wide Mojo configuration and
+ // initialization.
+ virtual void InitializeMojo(mojo::core::Configuration* config);
// Gets the list of service manifests with which to initialize the Service
// Manager. This list must describe the complete set of usable services in
diff --git a/chromium/services/service_manager/embedder/switches.cc b/chromium/services/service_manager/embedder/switches.cc
index 8337a14af77..7bc83d1a551 100644
--- a/chromium/services/service_manager/embedder/switches.cc
+++ b/chromium/services/service_manager/embedder/switches.cc
@@ -58,9 +58,6 @@ const char kServiceRequestChannelToken[] = "service-request-channel-token";
// global descriptor table.
const char kSharedFiles[] = "shared-files";
-// The prefix used when starting the zygote process. (i.e. 'gdb --args')
-const char kZygoteCmdPrefix[] = "zygote-cmd-prefix";
-
// Causes the process to run as a zygote.
const char kZygoteProcess[] = "zygote";
diff --git a/chromium/services/service_manager/embedder/switches.h b/chromium/services/service_manager/embedder/switches.h
index 548165e5d12..3b6690aa501 100644
--- a/chromium/services/service_manager/embedder/switches.h
+++ b/chromium/services/service_manager/embedder/switches.h
@@ -38,9 +38,6 @@ COMPONENT_EXPORT(SERVICE_MANAGER_EMBEDDER_SWITCHES)
extern const char kSharedFiles[];
COMPONENT_EXPORT(SERVICE_MANAGER_EMBEDDER_SWITCHES)
-extern const char kZygoteCmdPrefix[];
-
-COMPONENT_EXPORT(SERVICE_MANAGER_EMBEDDER_SWITCHES)
extern const char kZygoteProcess[];
} // namespace switches
diff --git a/chromium/services/service_manager/public/cpp/binder_registry.h b/chromium/services/service_manager/public/cpp/binder_registry.h
index 15ddeac97cd..2144d87dff2 100644
--- a/chromium/services/service_manager/public/cpp/binder_registry.h
+++ b/chromium/services/service_manager/public/cpp/binder_registry.h
@@ -10,6 +10,7 @@
#include <string>
#include "base/callback.h"
+#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/system/message_pipe.h"
@@ -27,19 +28,6 @@ class BinderRegistryWithArgs {
BinderRegistryWithArgs() {}
~BinderRegistryWithArgs() = default;
- // Adds an interface inferring the interface name via the templated
- // parameter Interface::Name_
- // Usage example: //services/service_manager/README.md#OnBindInterface
- template <typename Interface>
- void AddInterface(
- const base::RepeatingCallback<void(mojo::InterfaceRequest<Interface>,
- BinderArgs...)>& callback,
- const scoped_refptr<base::SequencedTaskRunner>& task_runner = nullptr) {
- SetInterfaceBinder(
- Interface::Name_,
- std::make_unique<CallbackBinder<Interface, BinderArgs...>>(
- callback, task_runner));
- }
template <typename Interface>
void AddInterface(
const base::RepeatingCallback<void(mojo::PendingReceiver<Interface>,
diff --git a/chromium/services/service_manager/public/cpp/connector.h b/chromium/services/service_manager/public/cpp/connector.h
index a3b4953978d..0453141851d 100644
--- a/chromium/services/service_manager/public/cpp/connector.h
+++ b/chromium/services/service_manager/public/cpp/connector.h
@@ -192,19 +192,6 @@ class SERVICE_MANAGER_PUBLIC_CPP_EXPORT Connector {
}
template <typename Interface>
- void BindInterface(const ServiceFilter& filter,
- mojo::InterfacePtr<Interface>* ptr) {
- BindInterface(filter, mojo::MakeRequest(ptr));
- }
-
- template <typename Interface>
- void BindInterface(const std::string& service_name,
- mojo::InterfacePtr<Interface>* ptr) {
- return BindInterface(ServiceFilter::ByName(service_name),
- mojo::MakeRequest(ptr));
- }
-
- template <typename Interface>
void BindInterface(const std::string& service_name,
mojo::PendingReceiver<Interface> receiver) {
return BindInterface(ServiceFilter::ByName(service_name),
diff --git a/chromium/services/service_manager/public/cpp/interface_binder.h b/chromium/services/service_manager/public/cpp/interface_binder.h
index 96e12e88d31..ac357f663ec 100644
--- a/chromium/services/service_manager/public/cpp/interface_binder.h
+++ b/chromium/services/service_manager/public/cpp/interface_binder.h
@@ -9,7 +9,6 @@
#include <utility>
#include "base/bind.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/system/message_pipe.h"
@@ -31,8 +30,8 @@ class InterfaceBinder {
virtual ~InterfaceBinder() {}
// Asks the InterfaceBinder to bind an implementation of the specified
- // interface to the request passed via |handle|. If the InterfaceBinder binds
- // an implementation it must take ownership of the request handle.
+ // interface to the receiver passed via |handle|. If the InterfaceBinder binds
+ // an implementation it must take ownership of the receiver handle.
virtual void BindInterface(const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle,
BinderArgs... args) = 0;
@@ -42,18 +41,12 @@ template <typename Interface, typename... BinderArgs>
class CallbackBinder : public InterfaceBinder<BinderArgs...> {
public:
using BindCallback =
- base::RepeatingCallback<void(mojo::InterfaceRequest<Interface>,
+ base::RepeatingCallback<void(mojo::PendingReceiver<Interface>,
BinderArgs...)>;
CallbackBinder(const BindCallback& callback,
const scoped_refptr<base::SequencedTaskRunner>& task_runner)
: callback_(callback), task_runner_(task_runner) {}
- CallbackBinder(
- const base::RepeatingCallback<void(mojo::PendingReceiver<Interface>,
- BinderArgs...)>& callback,
- const scoped_refptr<base::SequencedTaskRunner>& task_runner)
- : CallbackBinder(base::BindRepeating(&RunBindReceiverCallback, callback),
- task_runner) {}
~CallbackBinder() override = default;
private:
@@ -61,28 +54,28 @@ class CallbackBinder : public InterfaceBinder<BinderArgs...> {
void BindInterface(const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle,
BinderArgs... args) override {
- mojo::InterfaceRequest<Interface> request(std::move(handle));
+ mojo::PendingReceiver<Interface> receiver(std::move(handle));
if (task_runner_) {
task_runner_->PostTask(
FROM_HERE, base::BindOnce(&CallbackBinder::RunCallback, callback_,
- std::move(request), args...));
+ std::move(receiver), args...));
} else {
- RunCallback(callback_, std::move(request), args...);
+ RunCallback(callback_, std::move(receiver), args...);
}
}
static void RunCallback(const BindCallback& callback,
- mojo::InterfaceRequest<Interface> request,
+ mojo::PendingReceiver<Interface> receiver,
BinderArgs... args) {
- callback.Run(std::move(request), args...);
+ callback.Run(std::move(receiver), args...);
}
static void RunBindReceiverCallback(
const base::RepeatingCallback<void(mojo::PendingReceiver<Interface>,
BinderArgs...)>& callback,
- mojo::InterfaceRequest<Interface> request,
+ mojo::PendingReceiver<Interface> receiver,
BinderArgs... args) {
- callback.Run(std::move(request), args...);
+ callback.Run(std::move(receiver), args...);
}
const BindCallback callback_;
diff --git a/chromium/services/service_manager/public/cpp/interface_provider.h b/chromium/services/service_manager/public/cpp/interface_provider.h
index 6b5f693afc4..9d65071c00c 100644
--- a/chromium/services/service_manager/public/cpp/interface_provider.h
+++ b/chromium/services/service_manager/public/cpp/interface_provider.h
@@ -16,7 +16,7 @@ namespace service_manager {
// Encapsulates a mojo::PendingRemote|Remote<mojom::InterfaceProvider>
// implemented in a remote application. Provides two main features:
-// - a typesafe GetInterface() method for binding InterfacePtrs.
+// - a typesafe GetInterface() method for binding Interface remotes.
// - a testing API that allows local callbacks to be registered that bind
// requests for remote interfaces.
// An instance of this class is used by the GetInterface() methods on
@@ -87,18 +87,11 @@ class SERVICE_MANAGER_PUBLIC_CPP_EXPORT InterfaceProvider {
base::WeakPtr<InterfaceProvider> GetWeakPtr();
- // Binds a passed in interface pointer to an implementation of the interface
- // in the remote application using MakeRequest. The interface pointer can
- // immediately be used to start sending requests to the remote interface.
- // Uses templated parameters in order to work with weak interfaces in blink.
- template <typename... Args>
- void GetInterface(Args&&... args) {
- GetInterface(MakeRequest(std::forward<Args>(args)...));
- }
- template <typename Interface>
- void GetInterface(mojo::InterfaceRequest<Interface> request) {
- GetInterfaceByName(Interface::Name_, std::move(request.PassMessagePipe()));
- }
+ // Binds a passed in pending receiver to an implementation of the interface in
+ // the remote application. The mojo remote associated to the interface in the
+ // local application can immediately be used to start sending requests to the
+ // remote interface. Uses templated parameters in order to work with weak
+ // interfaces in blink.
template <typename Interface>
void GetInterface(mojo::PendingReceiver<Interface> receiver) {
GetInterfaceByName(Interface::Name_, receiver.PassPipe());
@@ -106,23 +99,7 @@ class SERVICE_MANAGER_PUBLIC_CPP_EXPORT InterfaceProvider {
void GetInterfaceByName(const std::string& name,
mojo::ScopedMessagePipeHandle request_handle);
- // Returns a callback to GetInterface<Interface>(). This can be passed to
- // BinderRegistry::AddInterface() to forward requests.
- template <typename Interface>
- base::RepeatingCallback<void(mojo::InterfaceRequest<Interface>)>
- CreateInterfaceFactory() {
- return base::BindRepeating(
- &InterfaceProvider::BindInterfaceRequestFromSource<Interface>,
- GetWeakPtr());
- }
-
private:
- template <typename Interface>
- void BindInterfaceRequestFromSource(
- mojo::InterfaceRequest<Interface> request) {
- GetInterface<Interface>(std::move(request));
- }
-
void SetBinderForName(
const std::string& name,
base::RepeatingCallback<void(mojo::ScopedMessagePipeHandle)> binder) {
diff --git a/chromium/services/service_manager/public/cpp/local_interface_provider.h b/chromium/services/service_manager/public/cpp/local_interface_provider.h
index abf1f739a6f..10e4e840ed1 100644
--- a/chromium/services/service_manager/public/cpp/local_interface_provider.h
+++ b/chromium/services/service_manager/public/cpp/local_interface_provider.h
@@ -6,8 +6,6 @@
#define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_INTERFACE_PROVIDER_BASE_H_
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/interface_ptr.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "services/service_manager/public/cpp/export.h"
@@ -18,19 +16,6 @@ class LocalInterfaceProvider {
public:
virtual ~LocalInterfaceProvider() = default;
- // Binds |ptr| to an implementation of Interface in the remote application.
- // |ptr| can immediately be used to start sending requests to the remote
- // interface.
- template <typename Interface>
- void GetInterface(mojo::InterfacePtr<Interface>* ptr) {
- mojo::MessagePipe pipe;
- ptr->Bind(mojo::InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u));
- GetInterface(Interface::Name_, std::move(pipe.handle1));
- }
- template <typename Interface>
- void GetInterface(mojo::InterfaceRequest<Interface> request) {
- GetInterface(Interface::Name_, std::move(request.PassMessagePipe()));
- }
template <typename Interface>
void GetInterface(mojo::PendingReceiver<Interface> receiver) {
GetInterface(Interface::Name_, std::move(receiver.PassPipe()));
diff --git a/chromium/services/service_manager/sandbox/BUILD.gn b/chromium/services/service_manager/sandbox/BUILD.gn
index 0e9bfbf0327..21749ad3322 100644
--- a/chromium/services/service_manager/sandbox/BUILD.gn
+++ b/chromium/services/service_manager/sandbox/BUILD.gn
@@ -79,6 +79,8 @@ component("sandbox") {
sources += [
"linux/bpf_ime_policy_linux.cc",
"linux/bpf_ime_policy_linux.h",
+ "linux/bpf_tts_policy_linux.cc",
+ "linux/bpf_tts_policy_linux.h",
]
}
if (is_mac) {
diff --git a/chromium/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc b/chromium/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc
index 2747e169d6a..0d178b90d10 100644
--- a/chromium/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc
+++ b/chromium/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc
@@ -28,10 +28,10 @@
#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/files/file_util.h"
-#include "base/fuchsia/default_context.h"
#include "base/fuchsia/default_job.h"
#include "base/fuchsia/filtered_service_directory.h"
#include "base/fuchsia/fuchsia_logging.h"
+#include "base/fuchsia/process_context.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/process.h"
@@ -167,7 +167,7 @@ SandboxPolicyFuchsia::SandboxPolicyFuchsia(service_manager::SandboxType type) {
service_directory_task_runner_ = base::ThreadTaskRunnerHandle::Get();
service_directory_ =
std::make_unique<base::fuchsia::FilteredServiceDirectory>(
- base::fuchsia::ComponentContextForCurrentProcess()->svc().get());
+ base::ComponentContextForProcess()->svc().get());
for (const char* service_name : kDefaultServices) {
service_directory_->AddService(service_name);
}
diff --git a/chromium/services/service_manager/sandbox/linux/bpf_tts_policy_linux.cc b/chromium/services/service_manager/sandbox/linux/bpf_tts_policy_linux.cc
new file mode 100644
index 00000000000..812072395ec
--- /dev/null
+++ b/chromium/services/service_manager/sandbox/linux/bpf_tts_policy_linux.cc
@@ -0,0 +1,34 @@
+// Copyright 2020 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 "services/service_manager/sandbox/linux/bpf_tts_policy_linux.h"
+
+#include <sys/socket.h>
+
+#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
+#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
+#include "sandbox/linux/syscall_broker/broker_process.h"
+#include "sandbox/linux/system_headers/linux_syscalls.h"
+#include "services/service_manager/sandbox/linux/sandbox_linux.h"
+
+using sandbox::bpf_dsl::Allow;
+using sandbox::bpf_dsl::ResultExpr;
+using sandbox::bpf_dsl::Trap;
+using sandbox::syscall_broker::BrokerProcess;
+
+namespace service_manager {
+
+TtsProcessPolicy::TtsProcessPolicy() {}
+
+TtsProcessPolicy::~TtsProcessPolicy() {}
+
+ResultExpr TtsProcessPolicy::EvaluateSyscall(int sysno) const {
+ auto* broker_process = SandboxLinux::GetInstance()->broker_process();
+ if (broker_process->IsSyscallAllowed(sysno))
+ return Trap(BrokerProcess::SIGSYS_Handler, broker_process);
+
+ return BPFBasePolicy::EvaluateSyscall(sysno);
+}
+
+} // namespace service_manager
diff --git a/chromium/services/service_manager/sandbox/linux/bpf_tts_policy_linux.h b/chromium/services/service_manager/sandbox/linux/bpf_tts_policy_linux.h
new file mode 100644
index 00000000000..a562a68cfce
--- /dev/null
+++ b/chromium/services/service_manager/sandbox/linux/bpf_tts_policy_linux.h
@@ -0,0 +1,27 @@
+// Copyright 2020 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 SERVICES_SERVICE_MANAGER_SANDBOX_LINUX_BPF_TTS_POLICY_LINUX_H_
+#define SERVICES_SERVICE_MANAGER_SANDBOX_LINUX_BPF_TTS_POLICY_LINUX_H_
+
+#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
+#include "services/service_manager/sandbox/export.h"
+#include "services/service_manager/sandbox/linux/bpf_base_policy_linux.h"
+
+namespace service_manager {
+
+class SERVICE_MANAGER_SANDBOX_EXPORT TtsProcessPolicy : public BPFBasePolicy {
+ public:
+ TtsProcessPolicy();
+ ~TtsProcessPolicy() override;
+
+ sandbox::bpf_dsl::ResultExpr EvaluateSyscall(int sysno) const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TtsProcessPolicy);
+};
+
+} // namespace service_manager
+
+#endif // SERVICES_SERVICE_MANAGER_SANDBOX_LINUX_BPF_TTS_POLICY_LINUX_H_
diff --git a/chromium/services/service_manager/sandbox/linux/sandbox_linux.h b/chromium/services/service_manager/sandbox/linux/sandbox_linux.h
index 9f67272c5e2..6a17f9edb63 100644
--- a/chromium/services/service_manager/sandbox/linux/sandbox_linux.h
+++ b/chromium/services/service_manager/sandbox/linux/sandbox_linux.h
@@ -9,7 +9,7 @@
#include <string>
#include <vector>
-#include "base/logging.h"
+#include "base/check_op.h"
#include "base/macros.h"
#include "base/posix/global_descriptors.h"
#include "sandbox/linux/syscall_broker/broker_command.h"
diff --git a/chromium/services/service_manager/sandbox/linux/sandbox_seccomp_bpf_linux.cc b/chromium/services/service_manager/sandbox/linux/sandbox_seccomp_bpf_linux.cc
index e2f22540a5a..1c16d68df91 100644
--- a/chromium/services/service_manager/sandbox/linux/sandbox_seccomp_bpf_linux.cc
+++ b/chromium/services/service_manager/sandbox/linux/sandbox_seccomp_bpf_linux.cc
@@ -54,6 +54,7 @@
#if defined(OS_CHROMEOS)
#include "services/service_manager/sandbox/linux/bpf_ime_policy_linux.h"
+#include "services/service_manager/sandbox/linux/bpf_tts_policy_linux.h"
#endif // defined(OS_CHROMEOS)
using sandbox::BaselinePolicy;
@@ -185,6 +186,8 @@ std::unique_ptr<BPFBasePolicy> SandboxSeccompBPF::PolicyForSandboxType(
#if defined(OS_CHROMEOS)
case SandboxType::kIme:
return std::make_unique<ImeProcessPolicy>();
+ case SandboxType::kTts:
+ return std::make_unique<TtsProcessPolicy>();
#endif // defined(OS_CHROMEOS)
case SandboxType::kZygoteIntermediateSandbox:
case SandboxType::kNoSandbox:
@@ -228,6 +231,7 @@ void SandboxSeccompBPF::RunSandboxSanityChecks(
} break;
#if defined(OS_CHROMEOS)
case SandboxType::kIme:
+ case SandboxType::kTts:
#endif // defined(OS_CHROMEOS)
case SandboxType::kAudio:
case SandboxType::kSharingService:
diff --git a/chromium/services/service_manager/sandbox/sandbox_type.cc b/chromium/services/service_manager/sandbox/sandbox_type.cc
index 9ea1cccb467..de79b63b7de 100644
--- a/chromium/services/service_manager/sandbox/sandbox_type.cc
+++ b/chromium/services/service_manager/sandbox/sandbox_type.cc
@@ -8,6 +8,7 @@
#include "base/check.h"
#include "base/feature_list.h"
+#include "base/logging.h"
#include "base/notreached.h"
#include "services/service_manager/sandbox/features.h"
#include "services/service_manager/sandbox/switches.h"
@@ -26,6 +27,7 @@ bool IsUnsandboxedSandboxType(SandboxType sandbox_type) {
service_manager::features::kXRSandbox);
case SandboxType::kProxyResolver:
case SandboxType::kPdfConversion:
+ case SandboxType::kIconReader:
return false;
#endif
case SandboxType::kAudio:
@@ -57,6 +59,7 @@ bool IsUnsandboxedSandboxType(SandboxType sandbox_type) {
#endif
#if defined(OS_CHROMEOS)
case SandboxType::kIme:
+ case SandboxType::kTts:
#endif
#if !defined(OS_MACOSX)
case SandboxType::kSharingService:
@@ -116,9 +119,11 @@ void SetCommandLineFlagsForSandboxType(base::CommandLine* command_line,
case SandboxType::kXrCompositing:
case SandboxType::kProxyResolver:
case SandboxType::kPdfConversion:
+ case SandboxType::kIconReader:
#endif // defined(OS_WIN)
#if defined(OS_CHROMEOS)
case SandboxType::kIme:
+ case SandboxType::kTts:
#endif // defined(OS_CHROMEOS)
#if !defined(OS_MACOSX)
case SandboxType::kSharingService:
@@ -237,10 +242,14 @@ std::string StringFromUtilitySandboxType(SandboxType sandbox_type) {
return switches::kProxyResolverSandbox;
case SandboxType::kPdfConversion:
return switches::kPdfConversionSandbox;
+ case SandboxType::kIconReader:
+ return switches::kIconReaderSandbox;
#endif // defined(OS_WIN)
#if defined(OS_CHROMEOS)
case SandboxType::kIme:
return switches::kImeSandbox;
+ case SandboxType::kTts:
+ return switches::kTtsSandbox;
#endif // defined(OS_CHROMEOS)
// The following are not utility processes so should not occur.
case SandboxType::kRenderer:
@@ -287,6 +296,8 @@ SandboxType UtilitySandboxTypeFromString(const std::string& sandbox_string) {
return SandboxType::kProxyResolver;
if (sandbox_string == switches::kPdfConversionSandbox)
return SandboxType::kPdfConversion;
+ if (sandbox_string == switches::kIconReaderSandbox)
+ return SandboxType::kIconReader;
#endif
if (sandbox_string == switches::kAudioSandbox)
return SandboxType::kAudio;
@@ -297,6 +308,8 @@ SandboxType UtilitySandboxTypeFromString(const std::string& sandbox_string) {
#if defined(OS_CHROMEOS)
if (sandbox_string == switches::kImeSandbox)
return SandboxType::kIme;
+ if (sandbox_string == switches::kTtsSandbox)
+ return SandboxType::kTts;
#endif // defined(OS_CHROMEOS)
return SandboxType::kUtility;
}
diff --git a/chromium/services/service_manager/sandbox/sandbox_type.h b/chromium/services/service_manager/sandbox/sandbox_type.h
index 0eb1e615939..b35e3950ccf 100644
--- a/chromium/services/service_manager/sandbox/sandbox_type.h
+++ b/chromium/services/service_manager/sandbox/sandbox_type.h
@@ -30,6 +30,9 @@ enum class SandboxType {
// The PDF conversion service process used in printing.
kPdfConversion,
+
+ // The icon reader service.
+ kIconReader,
#endif
#if defined(OS_FUCHSIA)
@@ -69,6 +72,8 @@ enum class SandboxType {
#if defined(OS_CHROMEOS)
kIme,
+ // Text-to-speech.
+ kTts,
#endif // defined(OS_CHROMEOS)
#if defined(OS_LINUX)
diff --git a/chromium/services/service_manager/sandbox/switches.cc b/chromium/services/service_manager/sandbox/switches.cc
index 863638ae365..e635d4e8eed 100644
--- a/chromium/services/service_manager/sandbox/switches.cc
+++ b/chromium/services/service_manager/sandbox/switches.cc
@@ -36,10 +36,12 @@ const char kVideoCaptureSandbox[] = "video_capture";
const char kPdfConversionSandbox[] = "pdf_conversion";
const char kProxyResolverSandbox[] = "proxy_resolver";
const char kXrCompositingSandbox[] = "xr_compositing";
+const char kIconReaderSandbox[] = "icon_reader";
#endif // OS_WIN
#if defined(OS_CHROMEOS)
const char kImeSandbox[] = "ime";
+const char kTtsSandbox[] = "tts";
#endif // OS_CHROMEOS
// Flags owned by the service manager sandbox.
@@ -80,6 +82,7 @@ const char kGpuSandboxAllowSysVShm[] = "gpu-sandbox-allow-sysv-shm";
const char kGpuSandboxFailuresFatal[] = "gpu-sandbox-failures-fatal";
// Disables the sandbox for all process types that are normally sandboxed.
+// Meant to be used as a browser-level switch for testing purposes only.
const char kNoSandbox[] = "no-sandbox";
#if defined(OS_LINUX)
diff --git a/chromium/services/service_manager/sandbox/switches.h b/chromium/services/service_manager/sandbox/switches.h
index 0deedde8296..6d66ab6c4f2 100644
--- a/chromium/services/service_manager/sandbox/switches.h
+++ b/chromium/services/service_manager/sandbox/switches.h
@@ -35,10 +35,12 @@ SERVICE_MANAGER_SANDBOX_EXPORT extern const char kVideoCaptureSandbox[];
SERVICE_MANAGER_SANDBOX_EXPORT extern const char kPdfConversionSandbox[];
SERVICE_MANAGER_SANDBOX_EXPORT extern const char kProxyResolverSandbox[];
SERVICE_MANAGER_SANDBOX_EXPORT extern const char kXrCompositingSandbox[];
+SERVICE_MANAGER_SANDBOX_EXPORT extern const char kIconReaderSandbox[];
#endif // OS_WIN
#if defined(OS_CHROMEOS)
SERVICE_MANAGER_SANDBOX_EXPORT extern const char kImeSandbox[];
+SERVICE_MANAGER_SANDBOX_EXPORT extern const char kTtsSandbox[];
#endif // OS_CHROMEOS
// Flags owned by the service manager sandbox.
diff --git a/chromium/services/service_manager/sandbox/win/sandbox_diagnostics.h b/chromium/services/service_manager/sandbox/win/sandbox_diagnostics.h
index 5470fe1ada6..1f89e7ee7a9 100644
--- a/chromium/services/service_manager/sandbox/win/sandbox_diagnostics.h
+++ b/chromium/services/service_manager/sandbox/win/sandbox_diagnostics.h
@@ -14,7 +14,6 @@
#include <vector>
#include "base/callback.h"
-#include "base/logging.h"
#include "base/sequenced_task_runner.h"
#include "base/values.h"
#include "sandbox/constants.h"
diff --git a/chromium/services/service_manager/sandbox/win/sandbox_win.cc b/chromium/services/service_manager/sandbox/win/sandbox_win.cc
index a05106e2611..cde75bd0710 100644
--- a/chromium/services/service_manager/sandbox/win/sandbox_win.cc
+++ b/chromium/services/service_manager/sandbox/win/sandbox_win.cc
@@ -33,6 +33,7 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
+#include "base/trace_event/trace_arguments.h"
#include "base/trace_event/trace_event.h"
#include "base/win/iat_patch_function.h"
#include "base/win/scoped_handle.h"
@@ -44,6 +45,7 @@
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "sandbox/win/src/sandbox_policy_base.h"
+#include "sandbox/win/src/sandbox_policy_diagnostic.h"
#include "sandbox/win/src/win_utils.h"
#include "services/service_manager/sandbox/features.h"
#include "services/service_manager/sandbox/sandbox_type.h"
@@ -150,6 +152,26 @@ const wchar_t* const kTroublesomeDlls[] = {
const base::Feature kEnableCsrssLockdownFeature{
"EnableCsrssLockdown", base::FEATURE_DISABLED_BY_DEFAULT};
+// Helps emit trace events for sandbox policy. This mediates memory between
+// chrome.exe and chrome.dll.
+class PolicyTraceHelper : public base::trace_event::ConvertableToTraceFormat {
+ public:
+ PolicyTraceHelper(sandbox::TargetPolicy* policy) {
+ // |info| must live until JsonString() output is copied.
+ std::unique_ptr<sandbox::PolicyInfo> info = policy->GetPolicyInfo();
+ json_string_ = std::string(info->JsonString());
+ }
+ ~PolicyTraceHelper() override = default;
+
+ // ConvertableToTraceFormat.
+ void AppendAsTraceFormat(std::string* out) const override {
+ out->append(json_string_);
+ }
+
+ private:
+ std::string json_string_;
+}; // PolicyTraceHelper
+
#if !defined(NACL_WIN64)
// Adds the policy rules for the path and path\ with the semantic |access|.
// If |children| is set to true, we need to add the wildcard rules to also
@@ -599,14 +621,15 @@ base::string16 GetAppContainerProfileName(
sandbox_type == SandboxType::kXrCompositing);
auto sha1 = base::SHA1HashString(appcontainer_id);
std::string sandbox_base_name = (sandbox_type == SandboxType::kXrCompositing)
- ? std::string("chrome.sandbox.xrdevice")
- : std::string("chrome.sandbox.gpu");
+ ? std::string("cr.sb.xr")
+ : std::string("cr.sb.gpu");
std::string profile_name = base::StrCat(
{sandbox_base_name, base::HexEncode(sha1.data(), sha1.size())});
// CreateAppContainerProfile requires that the profile name is at most 64
- // characters. The size of sha1 is a constant 40, so validate that the base
- // names are sufficiently short that the total length is valid.
- DCHECK_LE(profile_name.length(), 64U);
+ // characters but 50 on WCOS systems. The size of sha1 is a constant 40,
+ // so validate that the base names are sufficiently short that the total
+ // length is valid on all systems.
+ DCHECK_LE(profile_name.length(), 50U);
return base::UTF8ToWide(profile_name);
}
@@ -845,6 +868,7 @@ bool SandboxWin::InitTargetServices(sandbox::TargetServices* target_services) {
return sandbox::SBOX_ALL_OK == result;
}
+// static
sandbox::ResultCode SandboxWin::StartSandboxedProcess(
base::CommandLine* cmd_line,
const std::string& process_type,
@@ -929,7 +953,8 @@ sandbox::ResultCode SandboxWin::StartSandboxedProcess(
if (!cmd_line->HasSwitch(switches::kAllowThirdPartyModules))
mitigations |= sandbox::MITIGATION_FORCE_MS_SIGNED_BINS;
if (sandbox_type == SandboxType::kNetwork ||
- sandbox_type == SandboxType::kAudio) {
+ sandbox_type == SandboxType::kAudio ||
+ sandbox_type == SandboxType::kIconReader) {
mitigations |= sandbox::MITIGATION_DYNAMIC_CODE_DISABLE;
}
// TODO(wfh): Relax strict handle checks for network process until root cause
@@ -1017,20 +1042,17 @@ sandbox::ResultCode SandboxWin::StartSandboxedProcess(
cmd_line->GetCommandLineString().c_str(), policy, &last_warning,
&last_error, &temp_process_info);
- // TODO(1059129) Remove logging and underlying plumbing on expiry.
- // This must be logged after spawning the process as the policy
- // memory is not committed until the target process is attached to
- // the sandbox policy. Max is kPolMemSize from sandbox_policy_base.cc.
- if (result == sandbox::SBOX_ALL_OK) {
- UMA_HISTOGRAM_CUSTOM_COUNTS("Process.Sandbox.PolicyGlobalSizeOnSuccess",
- policy->GetPolicyGlobalSize(), 16, 14 * 4096,
- 50);
- }
-
base::win::ScopedProcessInformation target(temp_process_info);
TRACE_EVENT_END0("startup", "StartProcessWithAccess::LAUNCHPROCESS");
+ // Trace policy as processes are started. Useful for both failure and success.
+ TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("sandbox"), "processLaunch",
+ TRACE_EVENT_SCOPE_PROCESS, "sandboxType",
+ GetSandboxTypeInEnglish(delegate->GetSandboxType()),
+ "policy",
+ std::make_unique<PolicyTraceHelper>(policy.get()));
+
if (sandbox::SBOX_ALL_OK != result) {
base::UmaHistogramSparse("Process.Sandbox.Launch.Error", last_error);
if (result == sandbox::SBOX_ERROR_GENERIC)
@@ -1057,6 +1079,7 @@ sandbox::ResultCode SandboxWin::StartSandboxedProcess(
return sandbox::SBOX_ALL_OK;
}
+// static
sandbox::ResultCode SandboxWin::GetPolicyDiagnostics(
base::OnceCallback<void(base::Value)> response) {
CHECK(g_broker_services);
@@ -1072,4 +1095,44 @@ void BlocklistAddOneDllForTesting(const wchar_t* module_name,
BlocklistAddOneDll(module_name, check_in_browser, policy);
}
+// static
+std::string SandboxWin::GetSandboxTypeInEnglish(SandboxType sandbox_type) {
+ switch (sandbox_type) {
+ case SandboxType::kNoSandbox:
+ return "Unsandboxed";
+ case SandboxType::kNoSandboxAndElevatedPrivileges:
+ return "Unsandboxed (Elevated)";
+ case SandboxType::kXrCompositing:
+ return "XR Compositing";
+ case SandboxType::kRenderer:
+ return "Renderer";
+ case SandboxType::kUtility:
+ return "Utility";
+ case SandboxType::kGpu:
+ return "GPU";
+ case SandboxType::kPpapi:
+ return "PPAPI";
+ case SandboxType::kNetwork:
+ return "Network";
+ case SandboxType::kCdm:
+ return "CDM";
+ case SandboxType::kPrintCompositor:
+ return "Print Compositor";
+ case SandboxType::kAudio:
+ return "Audio";
+ case SandboxType::kSpeechRecognition:
+ return "Speech Recognition";
+ case SandboxType::kProxyResolver:
+ return "Proxy Resolver";
+ case SandboxType::kPdfConversion:
+ return "PDF Conversion";
+ case SandboxType::kSharingService:
+ return "Sharing";
+ case SandboxType::kVideoCapture:
+ return "Video Capture";
+ case SandboxType::kIconReader:
+ return "Icon Reader";
+ }
+}
+
} // namespace service_manager
diff --git a/chromium/services/service_manager/sandbox/win/sandbox_win.h b/chromium/services/service_manager/sandbox/win/sandbox_win.h
index b39b213ec05..6614a82461e 100644
--- a/chromium/services/service_manager/sandbox/win/sandbox_win.h
+++ b/chromium/services/service_manager/sandbox/win/sandbox_win.h
@@ -87,6 +87,9 @@ class SERVICE_MANAGER_SANDBOX_EXPORT SandboxWin {
// will be an empty value if an error is encountered.
static sandbox::ResultCode GetPolicyDiagnostics(
base::OnceCallback<void(base::Value)> response);
+
+ // Provides a friendly name for the sandbox for chrome://sandbox and tracing.
+ static std::string GetSandboxTypeInEnglish(SandboxType sandbox_type);
};
SERVICE_MANAGER_SANDBOX_EXPORT
diff --git a/chromium/services/service_manager/service_instance.h b/chromium/services/service_manager/service_instance.h
index 513d58c9acb..20a3700f130 100644
--- a/chromium/services/service_manager/service_instance.h
+++ b/chromium/services/service_manager/service_instance.h
@@ -12,7 +12,6 @@
#include <string>
#include "base/containers/unique_ptr_adapters.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
diff --git a/chromium/services/service_manager/service_manager.cc b/chromium/services/service_manager/service_manager.cc
index cb0a52ba8bd..ceb1ea74f24 100644
--- a/chromium/services/service_manager/service_manager.cc
+++ b/chromium/services/service_manager/service_manager.cc
@@ -86,9 +86,8 @@ class DefaultServiceProcessHost : public ServiceProcessHost {
#else
// TODO(https://crbug.com/781334): Support sandboxing.
CHECK_EQ(sandbox_type, SandboxType::kNoSandbox);
- return launcher_
- .Start(identity, SandboxType::kNoSandbox, std::move(callback))
- .PassInterface();
+ return launcher_.Start(identity, SandboxType::kNoSandbox,
+ std::move(callback));
#endif // defined(OS_IOS)
}
diff --git a/chromium/services/service_manager/service_process_launcher.cc b/chromium/services/service_manager/service_process_launcher.cc
index a87a5339a24..2a738f1ab64 100644
--- a/chromium/services/service_manager/service_process_launcher.cc
+++ b/chromium/services/service_manager/service_process_launcher.cc
@@ -93,9 +93,10 @@ ServiceProcessLauncher::~ServiceProcessLauncher() {
FROM_HERE, base::BindOnce(&ProcessState::StopInBackground, state_));
}
-mojom::ServicePtr ServiceProcessLauncher::Start(const Identity& target,
- SandboxType sandbox_type,
- ProcessReadyCallback callback) {
+mojo::PendingRemote<mojom::Service> ServiceProcessLauncher::Start(
+ const Identity& target,
+ SandboxType sandbox_type,
+ ProcessReadyCallback callback) {
DCHECK(!state_);
const base::CommandLine& parent_command_line =
@@ -139,7 +140,7 @@ mojom::ServicePtr ServiceProcessLauncher::Start(const Identity& target,
channel.PrepareToPassRemoteEndpoint(&handle_passing_info,
child_command_line.get());
mojo::OutgoingInvitation invitation;
- mojom::ServicePtr client =
+ auto client =
PassServiceRequestOnCommandLine(&invitation, child_command_line.get());
if (delegate_) {
@@ -160,14 +161,15 @@ mojom::ServicePtr ServiceProcessLauncher::Start(const Identity& target,
}
// static
-mojom::ServicePtr ServiceProcessLauncher::PassServiceRequestOnCommandLine(
+mojo::PendingRemote<mojom::Service>
+ServiceProcessLauncher::PassServiceRequestOnCommandLine(
mojo::OutgoingInvitation* invitation,
base::CommandLine* command_line) {
const auto attachment_name = base::NumberToString(base::RandUint64());
command_line->AppendSwitchASCII(switches::kServiceRequestAttachmentName,
attachment_name);
- return mojom::ServicePtr{
- mojom::ServicePtrInfo{invitation->AttachMessagePipe(attachment_name), 0}};
+ return mojo::PendingRemote<mojom::Service>(
+ invitation->AttachMessagePipe(attachment_name), 0);
}
base::ProcessId ServiceProcessLauncher::ProcessState::LaunchInBackground(
diff --git a/chromium/services/service_manager/service_process_launcher.h b/chromium/services/service_manager/service_process_launcher.h
index 12ad8867691..1b0b04ff5c5 100644
--- a/chromium/services/service_manager/service_process_launcher.h
+++ b/chromium/services/service_manager/service_process_launcher.h
@@ -15,6 +15,7 @@
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
#include "base/sequenced_task_runner.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/service_manager/public/mojom/service.mojom.h"
#include "services/service_manager/sandbox/sandbox_type.h"
#include "services/service_manager/service_process_launcher_delegate.h"
@@ -47,9 +48,9 @@ class ServiceProcessLauncher {
// |Start()|s the child process; calls |DidStart()| (on the thread on which
// |Start()| was called) when the child has been started (or failed to start).
- mojom::ServicePtr Start(const Identity& target,
- SandboxType sandbox_type,
- ProcessReadyCallback callback);
+ mojo::PendingRemote<mojom::Service> Start(const Identity& target,
+ SandboxType sandbox_type,
+ ProcessReadyCallback callback);
// Exposed publicly for use in tests. Creates a new Service pipe, passing the
// ServiceRequest end through |*invitation| with an identifier stashed in
@@ -57,7 +58,7 @@ class ServiceProcessLauncher {
// from the invitation.
//
// Returns the corresponding ServicePtr endpoint.
- static mojom::ServicePtr PassServiceRequestOnCommandLine(
+ static mojo::PendingRemote<mojom::Service> PassServiceRequestOnCommandLine(
mojo::OutgoingInvitation* invitation,
base::CommandLine* command_line);
diff --git a/chromium/services/service_manager/zygote/BUILD.gn b/chromium/services/service_manager/zygote/BUILD.gn
deleted file mode 100644
index da276ffcc78..00000000000
--- a/chromium/services/service_manager/zygote/BUILD.gn
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2018 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.
-
-import("//build/buildflag_header.gni")
-import("//build/config/nacl/config.gni")
-import("//services/service_manager/zygote/common/zygote_features.gni")
-
-if (is_linux) {
- component("zygote") {
- if (is_nacl_nonsfi) {
- # When running the nacl toolchain is_linux is false so *_linux.cc files are
- # excluded. Reset the filter so they are included.
- set_sources_assignment_filter([])
- }
-
- sources = [
- "common/common_sandbox_support_linux.cc",
- "common/common_sandbox_support_linux.h",
- "common/zygote_fork_delegate_linux.h",
- "common/zygote_handle.h",
- "host/zygote_communication_linux.cc",
- "host/zygote_communication_linux.h",
- "host/zygote_host_impl_linux.cc",
- "host/zygote_host_impl_linux.h",
- "zygote_linux.cc",
- "zygote_linux.h",
- "zygote_main.h",
- "zygote_main_linux.cc",
- ]
-
- if (use_zygote_handle) {
- sources += [
- "common/zygote_handle.h",
- "host/zygote_handle_linux.cc",
- ]
- }
-
- public_deps = [
- ":zygote_buildflags",
- ":zygote_util",
- ]
-
- deps = [
- "//base",
- "//base:i18n",
- "//ipc",
- "//sandbox",
- "//services/service_manager/embedder",
- "//services/service_manager/sandbox",
- "//third_party/icu",
- ]
-
- defines = [ "IS_SERVICE_MANAGER_ZYGOTE_IMPL" ]
- }
-}
-
-source_set("zygote_util") {
- if (is_nacl_nonsfi) {
- # When running the nacl toolchain is_linux is false so *_linux.cc files are
- # excluded. Reset the filter so they are included.
- set_sources_assignment_filter([])
- }
-
- sources = [
- "common/send_zygote_child_ping_linux.cc",
- "common/send_zygote_child_ping_linux.h",
- "common/zygote_commands_linux.h",
- ]
-
- deps = [
- "//base",
- "//services/service_manager/sandbox:sanitizer_buildflags",
- ]
-
- defines = [ "IS_SERVICE_MANAGER_ZYGOTE_IMPL" ]
-}
-
-buildflag_header("zygote_buildflags") {
- header = "common/zygote_buildflags.h"
- flags = [ "USE_ZYGOTE_HANDLE=$use_zygote_handle" ]
-}
diff --git a/chromium/services/service_manager/zygote/DEPS b/chromium/services/service_manager/zygote/DEPS
deleted file mode 100644
index ec69c8f59a8..00000000000
--- a/chromium/services/service_manager/zygote/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
- "+sandbox",
-]
diff --git a/chromium/services/service_manager/zygote/OWNERS b/chromium/services/service_manager/zygote/OWNERS
deleted file mode 100644
index d38314f3fdd..00000000000
--- a/chromium/services/service_manager/zygote/OWNERS
+++ /dev/null
@@ -1,7 +0,0 @@
-jln@chromium.org
-palmer@chromium.org
-rsesek@chromium.org
-tsepez@chromium.org
-
-# TEAM: security-dev@chromium.org
-# COMPONENT: Internals>Sandbox
diff --git a/chromium/services/service_manager/zygote/common/common_sandbox_support_linux.cc b/chromium/services/service_manager/zygote/common/common_sandbox_support_linux.cc
deleted file mode 100644
index 742fab4472b..00000000000
--- a/chromium/services/service_manager/zygote/common/common_sandbox_support_linux.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 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 "services/service_manager/zygote/common/common_sandbox_support_linux.h"
-
-#include "base/pickle.h"
-#include "base/posix/global_descriptors.h"
-#include "base/posix/unix_domain_socket.h"
-#include "services/service_manager/embedder/descriptors.h"
-#include "services/service_manager/sandbox/linux/sandbox_linux.h"
-
-namespace service_manager {
-
-#if !defined(OS_NACL_NONSFI)
-int SharedMemoryIPCSupport::MakeSharedMemorySegment(size_t length,
- bool executable) {
- base::Pickle request;
- request.WriteInt(
- service_manager::SandboxLinux::METHOD_MAKE_SHARED_MEMORY_SEGMENT);
- request.WriteUInt32(length);
- request.WriteBool(executable);
- uint8_t reply_buf[10];
- int result_fd;
- ssize_t result = base::UnixDomainSocket::SendRecvMsg(
- GetSandboxFD(), reply_buf, sizeof(reply_buf), &result_fd, request);
- if (result == -1)
- return -1;
- return result_fd;
-}
-#endif
-
-int GetSandboxFD() {
- return service_manager::kSandboxIPCChannel +
- base::GlobalDescriptors::kBaseDescriptor;
-}
-
-} // namespace service_manager
diff --git a/chromium/services/service_manager/zygote/common/common_sandbox_support_linux.h b/chromium/services/service_manager/zygote/common/common_sandbox_support_linux.h
deleted file mode 100644
index 051d8ba0318..00000000000
--- a/chromium/services/service_manager/zygote/common/common_sandbox_support_linux.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 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 SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_COMMON_SANDBOX_SUPPORT_LINUX_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_COMMON_SANDBOX_SUPPORT_LINUX_H_
-
-#include <stddef.h>
-
-#include "base/component_export.h"
-#include "build/build_config.h"
-
-class NaClListener;
-
-namespace service_manager {
-
-#if !defined(OS_NACL_NONSFI)
-// TODO(crbug.com/982879): Remove this when NaCl is unshipped.
-class COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE) SharedMemoryIPCSupport {
- private:
- friend class ::NaClListener;
-
- // Returns a file descriptor for a shared memory segment. The
- // executable flag indicates that the caller intends to use mprotect
- // with PROT_EXEC after making a mapping, but not that it intends to
- // mmap with PROT_EXEC in the first place. (Some systems, such as
- // ChromeOS, disallow PROT_EXEC in mmap on /dev/shm files but do allow
- // PROT_EXEC in mprotect on mappings from such files. This function
- // can yield an object that has that constraint.)
- static int MakeSharedMemorySegment(size_t length, bool executable);
-
- SharedMemoryIPCSupport() = delete;
-};
-#endif
-
-// Gets the well-known file descriptor on which we expect to find the
-// sandbox IPC channel.
-COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE) int GetSandboxFD();
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_COMMON_SANDBOX_SUPPORT_LINUX_H_
diff --git a/chromium/services/service_manager/zygote/common/send_zygote_child_ping_linux.cc b/chromium/services/service_manager/zygote/common/send_zygote_child_ping_linux.cc
deleted file mode 100644
index 1245398f52c..00000000000
--- a/chromium/services/service_manager/zygote/common/send_zygote_child_ping_linux.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 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 "services/service_manager/zygote/common/send_zygote_child_ping_linux.h"
-
-#include <vector>
-
-#include "base/posix/unix_domain_socket.h"
-#include "services/service_manager/zygote/common/zygote_commands_linux.h"
-
-namespace service_manager {
-
-bool SendZygoteChildPing(int fd) {
- return base::UnixDomainSocket::SendMsg(fd, kZygoteChildPingMessage,
- sizeof(kZygoteChildPingMessage),
- std::vector<int>());
-}
-
-} // namespace service_manager
diff --git a/chromium/services/service_manager/zygote/common/send_zygote_child_ping_linux.h b/chromium/services/service_manager/zygote/common/send_zygote_child_ping_linux.h
deleted file mode 100644
index 66aff241a95..00000000000
--- a/chromium/services/service_manager/zygote/common/send_zygote_child_ping_linux.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 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 SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_SEND_ZYGOTE_CHILD_PING_LINUX_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_SEND_ZYGOTE_CHILD_PING_LINUX_H_
-
-#include "base/component_export.h"
-
-namespace service_manager {
-
-// Sends a zygote child "ping" message to browser process via socket |fd|.
-// Returns true on success.
-COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE) bool SendZygoteChildPing(int fd);
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_SEND_ZYGOTE_CHILD_PING_LINUX_H_
diff --git a/chromium/services/service_manager/zygote/common/zygote_commands_linux.h b/chromium/services/service_manager/zygote/common/zygote_commands_linux.h
deleted file mode 100644
index b1d7c718a8d..00000000000
--- a/chromium/services/service_manager/zygote/common/zygote_commands_linux.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2012 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 SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_ZYGOTE_COMMANDS_LINUX_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_ZYGOTE_COMMANDS_LINUX_H_
-
-#include <stddef.h>
-
-#include "base/posix/global_descriptors.h"
-
-namespace service_manager {
-
-// Contents of the initial message sent from the zygote to the browser right
-// after it starts.
-static const char kZygoteBootMessage[] = "ZYGOTE_BOOT";
-
-// Contents of the initial message sent from the zygote to the browser when it
-// is ready to go.
-static const char kZygoteHelloMessage[] = "ZYGOTE_OK";
-
-// Message sent by zygote children to the browser so the browser can discover
-// the sending child's process ID.
-static const char kZygoteChildPingMessage[] = "CHILD_PING";
-
-// Maximum allowable length for messages sent to the zygote.
-const size_t kZygoteMaxMessageLength = 12288;
-
-// File descriptors initialized by the Zygote Host
-const int kZygoteSocketPairFd = base::GlobalDescriptors::kBaseDescriptor;
-
-// These are the command codes used on the wire between the browser and the
-// zygote.
-enum {
- // Fork off a new renderer.
- kZygoteCommandFork = 0,
-
- // Reap a renderer child.
- kZygoteCommandReap = 1,
-
- // Check what happened to a child process.
- kZygoteCommandGetTerminationStatus = 2,
-
- // Read a bitmask of kSandboxLinux*
- kZygoteCommandGetSandboxStatus = 3,
-
- // Not a real zygote command, but a subcommand used during the zygote fork
- // protocol. Sends the child's PID as seen from the browser process.
- kZygoteCommandForkRealPID = 4
-};
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_ZYGOTE_COMMANDS_LINUX_H_
diff --git a/chromium/services/service_manager/zygote/common/zygote_features.gni b/chromium/services/service_manager/zygote/common/zygote_features.gni
deleted file mode 100644
index c7580b35ff3..00000000000
--- a/chromium/services/service_manager/zygote/common/zygote_features.gni
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2018 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.
-
-use_zygote_handle = is_posix && !is_android && !is_mac
diff --git a/chromium/services/service_manager/zygote/common/zygote_fork_delegate_linux.h b/chromium/services/service_manager/zygote/common/zygote_fork_delegate_linux.h
deleted file mode 100644
index aec457b8750..00000000000
--- a/chromium/services/service_manager/zygote/common/zygote_fork_delegate_linux.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2012 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 SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_ZYGOTE_FORK_DELEGATE_LINUX_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_ZYGOTE_FORK_DELEGATE_LINUX_H_
-
-#include <unistd.h>
-
-#include <string>
-#include <vector>
-
-// TODO(jln) base::TerminationStatus should be forward declared when switching
-// to C++11.
-#include "base/process/kill.h"
-
-namespace service_manager {
-
-// The ZygoteForkDelegate allows the Chrome Linux zygote to delegate
-// fork operations to another class that knows how to do some
-// specialized version of fork.
-class ZygoteForkDelegate {
- public:
- // A ZygoteForkDelegate is created during Chrome linux zygote
- // initialization, and provides "fork()" functionality as an
- // alternative to forking the zygote. A new delegate is passed in
- // as an argument to ZygoteMain().
- virtual ~ZygoteForkDelegate() {}
-
- // Initialization happens in the zygote after it has been
- // started by ZygoteMain.
- // If |enable_layer1_sandbox| is true, the delegate must enable a
- // layer-1 sandbox such as the setuid sandbox.
- virtual void Init(int sandboxdesc, bool enable_layer1_sandbox) = 0;
-
- // After Init, supply a UMA_HISTOGRAM_ENUMERATION the delegate would like
- // reported to the browser process. (Note: Because these reports are
- // piggy-backed onto fork responses that don't otherwise contain UMA reports,
- // this method may not be called until much later.)
- virtual void InitialUMA(std::string* uma_name,
- int* uma_sample,
- int* uma_boundary_value) = 0;
-
- // Returns 'true' if the delegate would like to handle a given fork
- // request. Otherwise returns false. Optionally, fills in uma_name et al
- // with a report the helper wants to make via UMA_HISTOGRAM_ENUMERATION.
- virtual bool CanHelp(const std::string& process_type,
- std::string* uma_name,
- int* uma_sample,
- int* uma_boundary_value) = 0;
-
- // Indexes of FDs in the vector passed to Fork().
- enum {
- // Used to pass in the descriptor for talking to the Browser.
- // Because the children use ChannelMojo, this is actually the Mojo fd.
- kBrowserFDIndex,
- // The PID oracle is used in the protocol for discovering the
- // child process's real PID from within the SUID sandbox.
- // The child process is required to write to the socket after
- // successfully forking.
- kPIDOracleFDIndex,
- kNumPassedFDs // Number of FDs in the vector passed to Fork().
- };
-
- // Delegate forks, returning a -1 on failure. Outside the
- // suid sandbox, Fork() returns the Linux process ID.
- // This method is not aware of any potential pid namespaces, so it'll
- // return a raw pid just like fork() would.
- // Delegate is responsible for communicating the channel ID to the
- // newly created child process.
- virtual pid_t Fork(const std::string& process_type,
- const std::vector<int>& fds,
- const std::string& channel_id) = 0;
-
- // The fork delegate must also assume the role of waiting for its children
- // since the caller will not be their parents and cannot do it. |pid| here
- // should be a pid that has been returned by the Fork() method. i.e. This
- // method is completely unaware of eventual PID namespaces due to sandboxing.
- // |known_dead| indicates that the process is already dead and that a
- // blocking wait() should be performed. In this case, GetTerminationStatus()
- // will send a SIGKILL to the target process first.
- virtual bool GetTerminationStatus(pid_t pid,
- bool known_dead,
- base::TerminationStatus* status,
- int* exit_code) = 0;
-};
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_ZYGOTE_FORK_DELEGATE_LINUX_H_
diff --git a/chromium/services/service_manager/zygote/common/zygote_handle.h b/chromium/services/service_manager/zygote/common/zygote_handle.h
deleted file mode 100644
index 07efadf6807..00000000000
--- a/chromium/services/service_manager/zygote/common/zygote_handle.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 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 SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_ZYGOTE_HANDLE_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_ZYGOTE_HANDLE_H_
-
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/component_export.h"
-#include "base/files/scoped_file.h"
-#include "build/build_config.h"
-#include "services/service_manager/zygote/common/zygote_buildflags.h"
-
-#if !BUILDFLAG(USE_ZYGOTE_HANDLE)
-#error "Can not use zygote handles without USE_ZYGOTE_HANDLE"
-#endif
-
-namespace service_manager {
-
-#if defined(OS_POSIX)
-class ZygoteCommunication;
-using ZygoteHandle = ZygoteCommunication*;
-#else
-// Perhaps other ports may USE_ZYGOTE_HANDLE here somdeday.
-#error "Can not use zygote handles on this platform"
-#endif // defined(OS_POSIX)
-
-using ZygoteLaunchCallback =
- base::OnceCallback<pid_t(base::CommandLine*, base::ScopedFD*)>;
-
-// Allocates and initializes the global generic zygote process, and returns the
-// ZygoteHandle used to communicate with it. |launch_cb| is a callback that
-// should actually launch the process, after adding additional command line
-// switches to the ones composed by this function. It returns the pid created,
-// and provides a control fd for it.
-COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE)
-ZygoteHandle CreateGenericZygote(ZygoteLaunchCallback launch_cb);
-COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE) ZygoteHandle GetGenericZygote();
-
-// Similar to the above but for creating an unsandboxed zygote from which
-// processes which need non-generic sandboxes can be derived.
-COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE)
-ZygoteHandle CreateUnsandboxedZygote(ZygoteLaunchCallback launch_cb);
-COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE) ZygoteHandle GetUnsandboxedZygote();
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_COMMON_ZYGOTE_HANDLE_H_
diff --git a/chromium/services/service_manager/zygote/host/zygote_communication_linux.cc b/chromium/services/service_manager/zygote/host/zygote_communication_linux.cc
deleted file mode 100644
index a3a1fc73bea..00000000000
--- a/chromium/services/service_manager/zygote/host/zygote_communication_linux.cc
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright 2015 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 "services/service_manager/zygote/host/zygote_communication_linux.h"
-
-#include <string.h>
-#include <sys/socket.h>
-
-#include "base/base_switches.h"
-#include "base/command_line.h"
-#include "base/i18n/unicodestring.h"
-#include "base/logging.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/path_service.h"
-#include "base/pickle.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/posix/unix_domain_socket.h"
-#include "base/stl_util.h"
-#include "services/service_manager/embedder/result_codes.h"
-#include "services/service_manager/embedder/switches.h"
-#include "services/service_manager/sandbox/switches.h"
-#include "services/service_manager/zygote/common/zygote_commands_linux.h"
-#include "third_party/icu/source/i18n/unicode/timezone.h"
-
-namespace service_manager {
-
-ZygoteCommunication::ZygoteCommunication(ZygoteType type)
- : type_(type),
- pid_(),
- sandbox_status_(0),
- have_read_sandbox_status_word_(false),
- init_(false) {}
-
-ZygoteCommunication::~ZygoteCommunication() {}
-
-bool ZygoteCommunication::SendMessage(const base::Pickle& data,
- const std::vector<int>* fds) {
- DCHECK(control_fd_.is_valid());
- CHECK(data.size() <= kZygoteMaxMessageLength)
- << "Trying to send too-large message to zygote (sending " << data.size()
- << " bytes, max is " << kZygoteMaxMessageLength << ")";
- CHECK(!fds || fds->size() <= base::UnixDomainSocket::kMaxFileDescriptors)
- << "Trying to send message with too many file descriptors to zygote "
- << "(sending " << fds->size() << ", max is "
- << base::UnixDomainSocket::kMaxFileDescriptors << ")";
-
- return base::UnixDomainSocket::SendMsg(control_fd_.get(), data.data(),
- data.size(),
- fds ? *fds : std::vector<int>());
-}
-
-ssize_t ZygoteCommunication::ReadSandboxStatus() {
- DCHECK(control_fd_.is_valid());
- // At startup we send a kZygoteCommandGetSandboxStatus request to the zygote,
- // but don't wait for the reply. Thus, the first time that we read from the
- // zygote, we get the reply to that request.
- ssize_t bytes_read = HANDLE_EINTR(
- read(control_fd_.get(), &sandbox_status_, sizeof(sandbox_status_)));
- if (bytes_read != sizeof(sandbox_status_)) {
- return -1;
- }
- return bytes_read;
-}
-
-ssize_t ZygoteCommunication::ReadReply(void* buf, size_t buf_len) {
- DCHECK(control_fd_.is_valid());
- if (!have_read_sandbox_status_word_) {
- if (ReadSandboxStatus() == -1) {
- return -1;
- }
- have_read_sandbox_status_word_ = true;
- base::UmaHistogramSparse("Linux.SandboxStatus", sandbox_status_);
- }
-
- return HANDLE_EINTR(read(control_fd_.get(), buf, buf_len));
-}
-
-pid_t ZygoteCommunication::ForkRequest(
- const std::vector<std::string>& argv,
- const base::FileHandleMappingVector& mapping,
- const std::string& process_type) {
- DCHECK(init_);
-
- base::Pickle pickle;
- int raw_socks[2];
- PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, raw_socks));
- base::ScopedFD my_sock(raw_socks[0]);
- base::ScopedFD peer_sock(raw_socks[1]);
- CHECK(base::UnixDomainSocket::EnableReceiveProcessId(my_sock.get()));
-
- pickle.WriteInt(kZygoteCommandFork);
- pickle.WriteString(process_type);
- pickle.WriteInt(argv.size());
- for (std::vector<std::string>::const_iterator i = argv.begin();
- i != argv.end(); ++i)
- pickle.WriteString(*i);
- std::unique_ptr<icu::TimeZone> timezone(icu::TimeZone::createDefault());
- icu::UnicodeString timezone_id;
- pickle.WriteString16(
- base::i18n::UnicodeStringToString16(timezone->getID(timezone_id)));
-
- // Fork requests contain one file descriptor for the PID oracle, and one
- // more for each file descriptor mapping for the child process.
- const size_t num_fds_to_send = 1 + mapping.size();
- pickle.WriteInt(num_fds_to_send);
-
- std::vector<int> fds;
-
- // First FD to send is peer_sock.
- // TODO(morrita): Ideally, this should be part of the mapping so that
- // PosixFileDescriptorInfo can manages its lifetime.
- fds.push_back(peer_sock.get());
-
- // The rest come from mapping.
- for (const auto& item : mapping) {
- fds.push_back(item.first);
- pickle.WriteUInt32(item.second);
- }
-
- // Sanity check that we've populated |fds| correctly.
- DCHECK_EQ(num_fds_to_send, fds.size());
-
- pid_t pid;
- {
- base::AutoLock lock(control_lock_);
- if (!SendMessage(pickle, &fds))
- return base::kNullProcessHandle;
- peer_sock.reset();
-
- {
- char buf[sizeof(kZygoteChildPingMessage) + 1];
- std::vector<base::ScopedFD> recv_fds;
- base::ProcessId real_pid;
-
- ssize_t n = base::UnixDomainSocket::RecvMsgWithPid(
- my_sock.get(), buf, sizeof(buf), &recv_fds, &real_pid);
- if (n != sizeof(kZygoteChildPingMessage) ||
- 0 != memcmp(buf, kZygoteChildPingMessage,
- sizeof(kZygoteChildPingMessage))) {
- // Zygote children should still be trustworthy when they're supposed to
- // ping us, so something's broken if we don't receive a valid ping.
- LOG(ERROR) << "Did not receive ping from zygote child";
- NOTREACHED();
- real_pid = -1;
- }
- my_sock.reset();
-
- // Always send PID back to zygote.
- base::Pickle pid_pickle;
- pid_pickle.WriteInt(kZygoteCommandForkRealPID);
- pid_pickle.WriteInt(real_pid);
- if (!SendMessage(pid_pickle, nullptr))
- return base::kNullProcessHandle;
- }
-
- // Read the reply, which pickles the PID and an optional UMA enumeration.
- static const unsigned kMaxReplyLength = 2048;
- char buf[kMaxReplyLength];
- const ssize_t len = ReadReply(buf, sizeof(buf));
-
- base::Pickle reply_pickle(buf, len);
- base::PickleIterator iter(reply_pickle);
- if (len <= 0 || !iter.ReadInt(&pid))
- return base::kNullProcessHandle;
-
- // If there is a nonempty UMA name string, then there is a UMA
- // enumeration to record.
- std::string uma_name;
- int uma_sample;
- int uma_boundary_value;
- if (iter.ReadString(&uma_name) && !uma_name.empty() &&
- iter.ReadInt(&uma_sample) && iter.ReadInt(&uma_boundary_value)) {
- // We cannot use the UMA_HISTOGRAM_ENUMERATION macro here,
- // because that's only for when the name is the same every time.
- // Here we're using whatever name we got from the other side.
- // But since it's likely that the same one will be used repeatedly
- // (even though it's not guaranteed), we cache it here.
- static base::HistogramBase* uma_histogram;
- if (!uma_histogram || uma_histogram->histogram_name() != uma_name) {
- uma_histogram = base::LinearHistogram::FactoryGet(
- uma_name, 1, uma_boundary_value, uma_boundary_value + 1,
- base::HistogramBase::kUmaTargetedHistogramFlag);
- }
- uma_histogram->Add(uma_sample);
- }
-
- if (pid <= 0)
- return base::kNullProcessHandle;
- }
-
- ZygoteChildBorn(pid);
- return pid;
-}
-
-void ZygoteCommunication::EnsureProcessTerminated(pid_t process) {
- DCHECK(init_);
- base::Pickle pickle;
-
- pickle.WriteInt(kZygoteCommandReap);
- pickle.WriteInt(process);
- if (!SendMessage(pickle, nullptr))
- LOG(ERROR) << "Failed to send Reap message to zygote";
- ZygoteChildDied(process);
-}
-
-void ZygoteCommunication::ZygoteChildBorn(pid_t process) {
- base::AutoLock lock(child_tracking_lock_);
- bool new_element_inserted =
- list_of_running_zygote_children_.insert(process).second;
- DCHECK(new_element_inserted);
-}
-
-void ZygoteCommunication::ZygoteChildDied(pid_t process) {
- base::AutoLock lock(child_tracking_lock_);
- size_t num_erased = list_of_running_zygote_children_.erase(process);
- DCHECK_EQ(1U, num_erased);
-}
-
-void ZygoteCommunication::Init(
- base::OnceCallback<pid_t(base::CommandLine*, base::ScopedFD*)> launcher) {
- CHECK(!init_);
-
- base::FilePath chrome_path;
- CHECK(base::PathService::Get(base::FILE_EXE, &chrome_path));
-
- base::CommandLine cmd_line(chrome_path);
- cmd_line.AppendSwitchASCII(switches::kProcessType, switches::kZygoteProcess);
-
- if (type_ == ZygoteType::kUnsandboxed)
- cmd_line.AppendSwitch(switches::kNoZygoteSandbox);
-
- const base::CommandLine& browser_command_line =
- *base::CommandLine::ForCurrentProcess();
- if (browser_command_line.HasSwitch(switches::kZygoteCmdPrefix)) {
- cmd_line.PrependWrapper(
- browser_command_line.GetSwitchValueNative(switches::kZygoteCmdPrefix));
- }
- // Append any switches from the service manager that need to be forwarded on
- // to the zygote/renderers.
- static const char* const kForwardSwitches[] = {
- service_manager::switches::kAllowSandboxDebugging,
- service_manager::switches::kDisableInProcessStackTraces,
- service_manager::switches::kDisableSeccompFilterSandbox,
- service_manager::switches::kNoSandbox,
- };
- cmd_line.CopySwitchesFrom(browser_command_line, kForwardSwitches,
- base::size(kForwardSwitches));
-
- pid_ = std::move(launcher).Run(&cmd_line, &control_fd_);
-
- base::Pickle pickle;
- pickle.WriteInt(kZygoteCommandGetSandboxStatus);
- if (!SendMessage(pickle, nullptr))
- LOG(FATAL) << "Cannot communicate with zygote";
-
- init_ = true;
-}
-
-base::TerminationStatus ZygoteCommunication::GetTerminationStatus(
- base::ProcessHandle handle,
- bool known_dead,
- int* exit_code) {
- DCHECK(init_);
- base::Pickle pickle;
- pickle.WriteInt(kZygoteCommandGetTerminationStatus);
- pickle.WriteBool(known_dead);
- pickle.WriteInt(handle);
-
- static const unsigned kMaxMessageLength = 128;
- char buf[kMaxMessageLength];
- ssize_t len;
- {
- base::AutoLock lock(control_lock_);
- if (!SendMessage(pickle, nullptr))
- LOG(ERROR) << "Failed to send GetTerminationStatus message to zygote";
- len = ReadReply(buf, sizeof(buf));
- }
-
- // Set this now to handle the error cases.
- if (exit_code)
- *exit_code = RESULT_CODE_NORMAL_EXIT;
- int status = base::TERMINATION_STATUS_NORMAL_TERMINATION;
-
- if (len == -1) {
- PLOG(WARNING) << "Error reading message from zygote";
- } else if (len == 0) {
- LOG(WARNING) << "Socket closed prematurely.";
- } else {
- base::Pickle read_pickle(buf, len);
- int tmp_status, tmp_exit_code;
- base::PickleIterator iter(read_pickle);
- if (!iter.ReadInt(&tmp_status) || !iter.ReadInt(&tmp_exit_code)) {
- LOG(WARNING)
- << "Error parsing GetTerminationStatus response from zygote.";
- } else {
- if (exit_code)
- *exit_code = tmp_exit_code;
- status = tmp_status;
- }
- }
-
- if (status != base::TERMINATION_STATUS_STILL_RUNNING) {
- ZygoteChildDied(handle);
- }
- return static_cast<base::TerminationStatus>(status);
-}
-
-int ZygoteCommunication::GetSandboxStatus() {
- if (have_read_sandbox_status_word_) {
- return sandbox_status_;
- }
- if (ReadSandboxStatus() == -1) {
- return 0;
- }
- have_read_sandbox_status_word_ = true;
- base::UmaHistogramSparse("Linux.SandboxStatus", sandbox_status_);
- return sandbox_status_;
-}
-
-} // namespace service_manager
diff --git a/chromium/services/service_manager/zygote/host/zygote_communication_linux.h b/chromium/services/service_manager/zygote/host/zygote_communication_linux.h
deleted file mode 100644
index 77878c78bbf..00000000000
--- a/chromium/services/service_manager/zygote/host/zygote_communication_linux.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2015 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 SERVICES_SERVICE_MANAGER_ZYGOTE_HOST_ZYGOTE_COMMUNICATION_LINUX_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_HOST_ZYGOTE_COMMUNICATION_LINUX_H_
-
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <sys/types.h>
-
-#include "base/callback.h"
-#include "base/component_export.h"
-#include "base/files/scoped_file.h"
-#include "base/process/kill.h"
-#include "base/process/launch.h"
-#include "base/process/process_handle.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-class Pickle;
-} // namespace base
-
-namespace service_manager {
-
-// Handles interprocess communication with the Linux zygote process. The zygote
-// does not use standard Chrome IPC or mojo, see:
-// https://chromium.googlesource.com/chromium/src/+/master/docs/linux/sandbox_ipc.md
-class COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE) ZygoteCommunication {
- public:
- enum class ZygoteType { kSandboxed, kUnsandboxed };
- explicit ZygoteCommunication(ZygoteType type);
- ~ZygoteCommunication();
-
- void Init(
- base::OnceCallback<pid_t(base::CommandLine*, base::ScopedFD*)> launcher);
-
- // Tries to start a process of type indicated by process_type.
- // Returns its pid on success, otherwise base::kNullProcessHandle;
- pid_t ForkRequest(const std::vector<std::string>& command_line,
- const base::FileHandleMappingVector& mapping,
- const std::string& process_type);
-
- void EnsureProcessTerminated(pid_t process);
-
- // Should be called every time a Zygote child died.
- void ZygoteChildDied(pid_t process);
-
- // Get the termination status (and, optionally, the exit code) of
- // the process. |exit_code| is set to the exit code of the child
- // process. (|exit_code| may be NULL.)
- // Unfortunately the Zygote can not accurately figure out if a process
- // is already dead without waiting synchronously for it.
- // |known_dead| should be set to true when we already know that the process
- // is dead. When |known_dead| is false, processes could be seen as
- // still running, even when they're not. When |known_dead| is true, the
- // process will be SIGKILL-ed first (which should have no effect if it was
- // really dead). This is to prevent a waiting waitpid() from blocking in
- // a single-threaded Zygote. See https://crbug.com/157458.
- base::TerminationStatus GetTerminationStatus(base::ProcessHandle handle,
- bool known_dead,
- int* exit_code);
-
- // Returns the sandbox status of this zygote.
- int GetSandboxStatus();
-
- private:
- // Should be called every time a Zygote child is born.
- void ZygoteChildBorn(pid_t process);
-
- // Read the reply from the zygote.
- ssize_t ReadReply(void* buf, size_t buf_len);
-
- // Sends |data| to the zygote via |control_fd_|. If |fds| is non-NULL, the
- // included file descriptors will also be passed. The caller is responsible
- // for acquiring |control_lock_|.
- bool SendMessage(const base::Pickle& data, const std::vector<int>* fds);
-
- // Get the sandbox status from the zygote.
- ssize_t ReadSandboxStatus();
-
- // Indicates whether the Zygote starts unsandboxed or not.
- const ZygoteType type_;
-
- base::ScopedFD control_fd_; // the socket to the zygote.
- // A lock protecting all communication with the zygote. This lock must be
- // acquired before sending a command and released after the result has been
- // received.
- base::Lock control_lock_;
- // The pid of the zygote.
- pid_t pid_;
- // The list of running zygote children.
- std::set<pid_t> list_of_running_zygote_children_;
- // The lock to guard the list of running zygote children.
- base::Lock child_tracking_lock_;
- int sandbox_status_;
- bool have_read_sandbox_status_word_;
- // Set to true when the zygote is initialized successfully.
- bool init_;
-};
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_HOST_ZYGOTE_COMMUNICATION_LINUX_H_
diff --git a/chromium/services/service_manager/zygote/host/zygote_handle_linux.cc b/chromium/services/service_manager/zygote/host/zygote_handle_linux.cc
deleted file mode 100644
index 30f135244be..00000000000
--- a/chromium/services/service_manager/zygote/host/zygote_handle_linux.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2016 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 "services/service_manager/zygote/common/zygote_handle.h"
-
-#include "services/service_manager/zygote/host/zygote_communication_linux.h"
-
-namespace service_manager {
-namespace {
-
-// Intentionally leaked.
-ZygoteHandle g_generic_zygote = nullptr;
-ZygoteHandle g_unsandboxed_zygote = nullptr;
-
-} // namespace
-
-ZygoteHandle CreateGenericZygote(ZygoteLaunchCallback launch_cb) {
- CHECK(!g_generic_zygote);
- g_generic_zygote =
- new ZygoteCommunication(ZygoteCommunication::ZygoteType::kSandboxed);
- g_generic_zygote->Init(std::move(launch_cb));
- return g_generic_zygote;
-}
-
-ZygoteHandle GetGenericZygote() {
- CHECK(g_generic_zygote);
- return g_generic_zygote;
-}
-
-ZygoteHandle CreateUnsandboxedZygote(ZygoteLaunchCallback launch_cb) {
- CHECK(!g_unsandboxed_zygote);
- g_unsandboxed_zygote =
- new ZygoteCommunication(ZygoteCommunication::ZygoteType::kUnsandboxed);
- g_unsandboxed_zygote->Init(std::move(launch_cb));
- return g_unsandboxed_zygote;
-}
-
-ZygoteHandle GetUnsandboxedZygote() {
- CHECK(g_unsandboxed_zygote);
- return g_unsandboxed_zygote;
-}
-
-} // namespace service_manager
diff --git a/chromium/services/service_manager/zygote/host/zygote_host_impl_linux.cc b/chromium/services/service_manager/zygote/host/zygote_host_impl_linux.cc
deleted file mode 100644
index 08ecc3c80c0..00000000000
--- a/chromium/services/service_manager/zygote/host/zygote_host_impl_linux.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright (c) 2012 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 "services/service_manager/zygote/host/zygote_host_impl_linux.h"
-
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include "base/allocator/allocator_extension.h"
-#include "base/files/file_enumerator.h"
-#include "base/posix/unix_domain_socket.h"
-#include "base/process/kill.h"
-#include "base/process/memory.h"
-#include "base/strings/string_number_conversions.h"
-#include "build/build_config.h"
-#include "sandbox/linux/services/credentials.h"
-#include "sandbox/linux/services/namespace_sandbox.h"
-#include "sandbox/linux/suid/client/setuid_sandbox_host.h"
-#include "sandbox/linux/suid/common/sandbox.h"
-#include "services/service_manager/sandbox/linux/sandbox_linux.h"
-#include "services/service_manager/sandbox/switches.h"
-#include "services/service_manager/zygote/common/zygote_commands_linux.h"
-
-namespace service_manager {
-
-namespace {
-
-// Receive a fixed message on fd and return the sender's PID.
-// Returns true if the message received matches the expected message.
-bool ReceiveFixedMessage(int fd,
- const char* expect_msg,
- size_t expect_len,
- base::ProcessId* sender_pid) {
- // Allocate an extra byte of buffer space so we can check that we received
- // exactly |expect_len| bytes, and the message wasn't just truncated to fit.
- char buf[expect_len + 1];
- std::vector<base::ScopedFD> fds_vec;
-
- const ssize_t len = base::UnixDomainSocket::RecvMsgWithPid(
- fd, buf, sizeof(buf), &fds_vec, sender_pid);
- if (static_cast<size_t>(len) != expect_len)
- return false;
- if (memcmp(buf, expect_msg, expect_len) != 0)
- return false;
- if (!fds_vec.empty())
- return false;
- return true;
-}
-
-} // namespace
-
-// static
-ZygoteHost* ZygoteHost::GetInstance() {
- return ZygoteHostImpl::GetInstance();
-}
-
-ZygoteHostImpl::ZygoteHostImpl()
- : use_namespace_sandbox_(false),
- use_suid_sandbox_(false),
- use_suid_sandbox_for_adj_oom_score_(false),
- sandbox_binary_(),
- zygote_pids_lock_(),
- zygote_pids_() {}
-
-ZygoteHostImpl::~ZygoteHostImpl() {}
-
-// static
-ZygoteHostImpl* ZygoteHostImpl::GetInstance() {
- return base::Singleton<ZygoteHostImpl>::get();
-}
-
-void ZygoteHostImpl::Init(const base::CommandLine& command_line) {
- if (command_line.HasSwitch(service_manager::switches::kNoSandbox)) {
- return;
- }
-
- // Exit early if running as root without --no-sandbox. See
- // https://crbug.com/638180.
- // When running as root with the sandbox enabled, the browser process
- // crashes on zygote initialization. Running as root with the sandbox
- // is not supported, and if Chrome were able to display UI it would be showing
- // an error message. With the zygote crashing it doesn't even get to that,
- // so print an error message on the console.
- uid_t uid = 0;
- gid_t gid = 0;
- if (!sandbox::Credentials::GetRESIds(&uid, &gid) || uid == 0) {
- LOG(ERROR) << "Running as root without --"
- << service_manager::switches::kNoSandbox
- << " is not supported. See https://crbug.com/638180.";
- exit(EXIT_FAILURE);
- }
-
- {
- std::unique_ptr<sandbox::SetuidSandboxHost> setuid_sandbox_host(
- sandbox::SetuidSandboxHost::Create());
- sandbox_binary_ = setuid_sandbox_host->GetSandboxBinaryPath().value();
- }
-
- if (!command_line.HasSwitch(
- service_manager::switches::kDisableNamespaceSandbox) &&
- sandbox::Credentials::CanCreateProcessInNewUserNS()) {
- use_namespace_sandbox_ = true;
- } else if (!command_line.HasSwitch(
- service_manager::switches::kDisableSetuidSandbox) &&
- !sandbox_binary_.empty()) {
- use_suid_sandbox_ = true;
-
- // Use the SUID sandbox for adjusting OOM scores when we are using
- // the setuid sandbox. This is needed beacuse the processes are
- // non-dumpable, so /proc/pid/oom_score_adj can only be written by
- // root.
- use_suid_sandbox_for_adj_oom_score_ = use_suid_sandbox_;
- } else {
- LOG(FATAL)
- << "No usable sandbox! Update your kernel or see "
- "https://chromium.googlesource.com/chromium/src/+/master/"
- "docs/linux/suid_sandbox_development.md for more information on "
- "developing with the SUID sandbox. "
- "If you want to live dangerously and need an immediate workaround, "
- "you can try using --"
- << service_manager::switches::kNoSandbox << ".";
- }
-}
-
-void ZygoteHostImpl::AddZygotePid(pid_t pid) {
- base::AutoLock lock(zygote_pids_lock_);
- zygote_pids_.insert(pid);
-}
-
-bool ZygoteHostImpl::IsZygotePid(pid_t pid) {
- base::AutoLock lock(zygote_pids_lock_);
- return zygote_pids_.find(pid) != zygote_pids_.end();
-}
-
-void ZygoteHostImpl::SetRendererSandboxStatus(int status) {
- renderer_sandbox_status_ = status;
-}
-
-int ZygoteHostImpl::GetRendererSandboxStatus() const {
- return renderer_sandbox_status_;
-}
-
-pid_t ZygoteHostImpl::LaunchZygote(
- base::CommandLine* cmd_line,
- base::ScopedFD* control_fd,
- base::FileHandleMappingVector additional_remapped_fds) {
- int fds[2];
- CHECK_EQ(0, socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds));
- CHECK(base::UnixDomainSocket::EnableReceiveProcessId(fds[0]));
-
- base::LaunchOptions options;
- options.fds_to_remap = std::move(additional_remapped_fds);
- options.fds_to_remap.emplace_back(fds[1], kZygoteSocketPairFd);
-
- const bool is_sandboxed_zygote =
- !cmd_line->HasSwitch(service_manager::switches::kNoZygoteSandbox);
-
- base::ScopedFD dummy_fd;
- if (is_sandboxed_zygote && use_suid_sandbox_) {
- std::unique_ptr<sandbox::SetuidSandboxHost> sandbox_host(
- sandbox::SetuidSandboxHost::Create());
- sandbox_host->PrependWrapper(cmd_line);
- sandbox_host->SetupLaunchOptions(&options, &dummy_fd);
- sandbox_host->SetupLaunchEnvironment();
- }
-
- base::Process process =
- (is_sandboxed_zygote && use_namespace_sandbox_)
- ? sandbox::NamespaceSandbox::LaunchProcess(*cmd_line, options)
- : base::LaunchProcess(*cmd_line, options);
- CHECK(process.IsValid()) << "Failed to launch zygote process";
-
- dummy_fd.reset();
- close(fds[1]);
- control_fd->reset(fds[0]);
-
- pid_t pid = process.Pid();
-
- if (is_sandboxed_zygote && (use_namespace_sandbox_ || use_suid_sandbox_)) {
- // The namespace and SUID sandbox will execute the zygote in a new
- // PID namespace, and the main zygote process will then fork from
- // there. Watch now our elaborate dance to find and validate the
- // zygote's PID.
-
- // First we receive a message from the zygote boot process.
- base::ProcessId boot_pid;
- CHECK(ReceiveFixedMessage(fds[0], kZygoteBootMessage,
- sizeof(kZygoteBootMessage), &boot_pid));
-
- // Within the PID namespace, the zygote boot process thinks it's PID 1,
- // but its real PID can never be 1. This gives us a reliable test that
- // the kernel is translating the sender's PID to our namespace.
- CHECK_GT(boot_pid, 1)
- << "Received invalid process ID for zygote; kernel might be too old? "
- "See crbug.com/357670 or try using --"
- << service_manager::switches::kNoSandbox << " to workaround.";
-
- // Now receive the message that the zygote's ready to go, along with the
- // main zygote process's ID.
- pid_t real_pid;
- CHECK(ReceiveFixedMessage(fds[0], kZygoteHelloMessage,
- sizeof(kZygoteHelloMessage), &real_pid));
- CHECK_GT(real_pid, 1);
-
- if (real_pid != pid) {
- // Reap the sandbox.
- base::EnsureProcessGetsReaped(std::move(process));
- }
- pid = real_pid;
- }
-
- AddZygotePid(pid);
- return pid;
-}
-
-#if !defined(OS_OPENBSD)
-void ZygoteHostImpl::AdjustRendererOOMScore(base::ProcessHandle pid,
- int score) {
- // 1) You can't change the oom_score_adj of a non-dumpable process
- // (EPERM) unless you're root. Because of this, we can't set the
- // oom_adj from the browser process.
- //
- // 2) We can't set the oom_score_adj before entering the sandbox
- // because the zygote is in the sandbox and the zygote is as
- // critical as the browser process. Its oom_adj value shouldn't
- // be changed.
- //
- // 3) A non-dumpable process can't even change its own oom_score_adj
- // because it's root owned 0644. The sandboxed processes don't
- // even have /proc, but one could imagine passing in a descriptor
- // from outside.
- //
- // So, in the normal case, we use the SUID binary to change it for us.
- // However, Fedora (and other SELinux systems) don't like us touching other
- // process's oom_score_adj (or oom_adj) values
- // (https://bugzilla.redhat.com/show_bug.cgi?id=581256).
- //
- // The offical way to get the SELinux mode is selinux_getenforcemode, but I
- // don't want to add another library to the build as it's sure to cause
- // problems with other, non-SELinux distros.
- //
- // So we just check for files in /selinux. This isn't foolproof, but it's not
- // bad and it's easy.
-
- static bool selinux;
- static bool selinux_valid = false;
-
- if (!selinux_valid) {
- const base::FilePath kSelinuxPath("/selinux");
- base::FileEnumerator en(kSelinuxPath, false, base::FileEnumerator::FILES);
- bool has_selinux_files = !en.Next().empty();
-
- selinux =
- has_selinux_files && access(kSelinuxPath.value().c_str(), X_OK) == 0;
- selinux_valid = true;
- }
-
- if (!use_suid_sandbox_for_adj_oom_score_) {
- if (!base::AdjustOOMScore(pid, score))
- PLOG(ERROR) << "Failed to adjust OOM score of renderer with pid " << pid;
- return;
- }
-
- if (selinux)
- return;
-
- // If heap profiling is running, these processes are not exiting, at least
- // on ChromeOS. The easiest thing to do is not launch them when profiling.
- // TODO(stevenjb): Investigate further and fix.
- if (base::allocator::IsHeapProfilerRunning())
- return;
-
- std::vector<std::string> adj_oom_score_cmdline;
- adj_oom_score_cmdline.push_back(sandbox_binary_);
- adj_oom_score_cmdline.push_back(sandbox::kAdjustOOMScoreSwitch);
- adj_oom_score_cmdline.push_back(base::NumberToString(pid));
- adj_oom_score_cmdline.push_back(base::NumberToString(score));
-
- // sandbox_helper_process is a setuid binary.
- base::LaunchOptions options;
- options.allow_new_privs = true;
-
- base::Process sandbox_helper_process =
- base::LaunchProcess(adj_oom_score_cmdline, options);
- if (sandbox_helper_process.IsValid())
- base::EnsureProcessGetsReaped(std::move(sandbox_helper_process));
-}
-#endif
-
-} // namespace service_manager
diff --git a/chromium/services/service_manager/zygote/host/zygote_host_impl_linux.h b/chromium/services/service_manager/zygote/host/zygote_host_impl_linux.h
deleted file mode 100644
index 64d6c45680d..00000000000
--- a/chromium/services/service_manager/zygote/host/zygote_host_impl_linux.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012 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 SERVICES_SERVICE_MANAGER_ZYGOTE_HOST_ZYGOTE_HOST_IMPL_LINUX_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_HOST_ZYGOTE_HOST_IMPL_LINUX_H_
-
-#include <sys/types.h>
-
-#include <set>
-#include <string>
-
-#include "base/command_line.h"
-#include "base/component_export.h"
-#include "base/files/scoped_file.h"
-#include "base/process/launch.h"
-#include "base/process/process_handle.h"
-#include "base/synchronization/lock.h"
-
-#include "services/service_manager/zygote/zygote_host_linux.h"
-
-namespace base {
-template <typename Type>
-struct DefaultSingletonTraits;
-} // namespace base
-
-namespace service_manager {
-
-class COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE) ZygoteHostImpl
- : public ZygoteHost {
- public:
- // Returns the singleton instance.
- static ZygoteHostImpl* GetInstance();
-
- void Init(const base::CommandLine& cmd_line);
-
- // Returns whether or not this pid is the pid of a zygote.
- bool IsZygotePid(pid_t pid) override;
-
- void SetRendererSandboxStatus(int status);
- int GetRendererSandboxStatus() const override;
-
- pid_t LaunchZygote(base::CommandLine* cmd_line,
- base::ScopedFD* control_fd,
- base::FileHandleMappingVector additional_remapped_fds);
-
- void AdjustRendererOOMScore(base::ProcessHandle process_handle,
- int score) override;
- bool HasZygote() { return !zygote_pids_.empty(); }
-
- private:
- friend struct base::DefaultSingletonTraits<ZygoteHostImpl>;
-
- ZygoteHostImpl();
- ~ZygoteHostImpl() override;
-
- // Tells the ZygoteHost the PIDs of all the zygotes.
- void AddZygotePid(pid_t pid);
-
- int renderer_sandbox_status_;
-
- bool use_namespace_sandbox_;
- bool use_suid_sandbox_;
- bool use_suid_sandbox_for_adj_oom_score_;
- std::string sandbox_binary_;
-
- // This lock protects the |zygote_pids_| set.
- base::Lock zygote_pids_lock_;
- // This is a set of PIDs representing all the running zygotes.
- std::set<pid_t> zygote_pids_;
-};
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_HOST_ZYGOTE_HOST_IMPL_LINUX_H_
diff --git a/chromium/services/service_manager/zygote/zygote_host_linux.h b/chromium/services/service_manager/zygote/zygote_host_linux.h
deleted file mode 100644
index 8e6416debe6..00000000000
--- a/chromium/services/service_manager/zygote/zygote_host_linux.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2012 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 SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_HOST_LINUX_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_HOST_LINUX_H_
-
-#include <unistd.h>
-
-#include "base/component_export.h"
-#include "base/process/process.h"
-
-namespace service_manager {
-
-// https://chromium.googlesource.com/chromium/src/+/master/docs/linux/zygote.md
-
-// The zygote host is an interface, in the browser process, to the zygote
-// process.
-class ZygoteHost {
- public:
- // Returns the singleton instance.
- static COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE) ZygoteHost* GetInstance();
-
- virtual ~ZygoteHost() {}
-
- // Returns the pid of the Zygote process.
- virtual bool IsZygotePid(pid_t pid) = 0;
-
- // Returns an int which is a bitmask of kSandboxLinux* values. Only valid
- // after the first render has been forked.
- virtual int GetRendererSandboxStatus() const = 0;
-
- // Adjust the OOM score of the given renderer's PID. The allowed
- // range for the score is [0, 1000], where higher values are more
- // likely to be killed by the OOM killer.
- virtual void AdjustRendererOOMScore(base::ProcessHandle process_handle,
- int score) = 0;
-};
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_HOST_LINUX_H_
diff --git a/chromium/services/service_manager/zygote/zygote_linux.cc b/chromium/services/service_manager/zygote/zygote_linux.cc
deleted file mode 100644
index aa601ab28d7..00000000000
--- a/chromium/services/service_manager/zygote/zygote_linux.cc
+++ /dev/null
@@ -1,659 +0,0 @@
-// Copyright (c) 2012 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 "services/service_manager/zygote/zygote_linux.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <utility>
-
-#include "base/command_line.h"
-#include "base/files/file_util.h"
-#include "base/linux_util.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/pickle.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/posix/global_descriptors.h"
-#include "base/posix/unix_domain_socket.h"
-#include "base/process/kill.h"
-#include "base/process/launch.h"
-#include "base/process/process.h"
-#include "base/process/process_handle.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-#include "build/build_config.h"
-#include "ipc/ipc_channel.h"
-#include "sandbox/linux/services/credentials.h"
-#include "sandbox/linux/services/namespace_sandbox.h"
-#include "services/service_manager/embedder/descriptors.h"
-#include "services/service_manager/embedder/result_codes.h"
-#include "services/service_manager/embedder/set_process_title.h"
-#include "services/service_manager/embedder/switches.h"
-#include "services/service_manager/sandbox/linux/sandbox_linux.h"
-#include "services/service_manager/sandbox/sandbox.h"
-#include "services/service_manager/zygote/common/send_zygote_child_ping_linux.h"
-#include "services/service_manager/zygote/common/zygote_commands_linux.h"
-#include "services/service_manager/zygote/common/zygote_fork_delegate_linux.h"
-#include "third_party/icu/source/i18n/unicode/timezone.h"
-
-// See
-// https://chromium.googlesource.com/chromium/src/+/master/docs/linux/zygote.md
-
-namespace service_manager {
-
-namespace {
-
-// NOP function. See below where this handler is installed.
-void SIGCHLDHandler(int signal) {}
-
-int LookUpFd(const base::GlobalDescriptors::Mapping& fd_mapping, uint32_t key) {
- for (size_t index = 0; index < fd_mapping.size(); ++index) {
- if (fd_mapping[index].key == key)
- return fd_mapping[index].fd;
- }
- return -1;
-}
-
-void KillAndReap(pid_t pid, ZygoteForkDelegate* helper) {
- if (helper) {
- // Helper children may be forked in another PID namespace, so |pid| might
- // be meaningless to us; or we just might not be able to directly send it
- // signals. So we can't kill it.
- // Additionally, we're not its parent, so we can't reap it anyway.
- // TODO(mdempsky): Extend the ZygoteForkDelegate API to handle this.
- LOG(WARNING) << "Unable to kill or reap helper children";
- return;
- }
-
- // Kill the child process in case it's not already dead, so we can safely
- // perform a blocking wait.
- PCHECK(0 == kill(pid, SIGKILL));
- PCHECK(pid == HANDLE_EINTR(waitpid(pid, nullptr, 0)));
-}
-
-} // namespace
-
-Zygote::Zygote(int sandbox_flags,
- std::vector<std::unique_ptr<ZygoteForkDelegate>> helpers,
- const base::GlobalDescriptors::Descriptor& ipc_backchannel)
- : sandbox_flags_(sandbox_flags),
- helpers_(std::move(helpers)),
- initial_uma_index_(0),
- to_reap_(),
- ipc_backchannel_(ipc_backchannel) {}
-
-Zygote::~Zygote() {}
-
-bool Zygote::ProcessRequests() {
- // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
- // browser on it.
- // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel.
- // See
- // https://chromium.googlesource.com/chromium/src/+/master/docs/linux/sandbox_ipc.md
-
- // We need to accept SIGCHLD, even though our handler is a no-op because
- // otherwise we cannot wait on children. (According to POSIX 2001.)
- struct sigaction action;
- memset(&action, 0, sizeof(action));
- action.sa_handler = &SIGCHLDHandler;
- PCHECK(sigaction(SIGCHLD, &action, nullptr) == 0);
-
- // Block SIGCHLD until a child might be ready to reap.
- sigset_t sigset;
- sigset_t orig_sigmask;
- PCHECK(sigemptyset(&sigset) == 0);
- PCHECK(sigaddset(&sigset, SIGCHLD) == 0);
- PCHECK(sigprocmask(SIG_BLOCK, &sigset, &orig_sigmask) == 0);
-
- if (UsingSUIDSandbox() || UsingNSSandbox()) {
- // Let the ZygoteHost know we are ready to go.
- // The receiving code is in
- // content/browser/zygote_host/zygote_host_impl_linux.cc.
- bool r = base::UnixDomainSocket::SendMsg(
- kZygoteSocketPairFd, kZygoteHelloMessage, sizeof(kZygoteHelloMessage),
- std::vector<int>());
-#if defined(OS_CHROMEOS)
- LOG_IF(WARNING, !r) << "Sending zygote magic failed";
- // Exit normally on chromeos because session manager may send SIGTERM
- // right after the process starts and it may fail to send zygote magic
- // number to browser process.
- if (!r)
- _exit(service_manager::RESULT_CODE_NORMAL_EXIT);
-#else
- CHECK(r) << "Sending zygote magic failed";
-#endif
- }
-
- sigset_t ppoll_sigmask = orig_sigmask;
- PCHECK(sigdelset(&ppoll_sigmask, SIGCHLD) == 0);
- struct pollfd pfd;
- pfd.fd = kZygoteSocketPairFd;
- pfd.events = POLLIN;
-
- struct timespec timeout;
- timeout.tv_sec = 2;
- timeout.tv_nsec = 0;
-
- for (;;) {
- struct timespec* timeout_ptr = nullptr;
- if (!to_reap_.empty())
- timeout_ptr = &timeout;
- int rc = ppoll(&pfd, 1, timeout_ptr, &ppoll_sigmask);
- PCHECK(rc >= 0 || errno == EINTR);
- ReapChildren();
-
- if (pfd.revents & POLLIN) {
- // This function call can return multiple times, once per fork().
- if (HandleRequestFromBrowser(kZygoteSocketPairFd)) {
- PCHECK(sigprocmask(SIG_SETMASK, &orig_sigmask, nullptr) == 0);
- return true;
- }
- }
- }
- // The loop should not be exited unless a request was successfully processed.
- NOTREACHED();
- return false;
-}
-
-bool Zygote::ReapChild(const base::TimeTicks& now, ZygoteProcessInfo* child) {
- pid_t pid = child->internal_pid;
- pid_t r = HANDLE_EINTR(waitpid(pid, nullptr, WNOHANG));
- if (r > 0) {
- if (r != pid) {
- DLOG(ERROR) << "While waiting for " << pid
- << " to terminate, "
- "waitpid returned "
- << r;
- }
- return r == pid;
- }
- if ((now - child->time_of_reap_request).InSeconds() < 2) {
- return false;
- }
- // If the process has been requested reaped >= 2 seconds ago, kill it.
- if (!child->sent_sigkill) {
- if (kill(pid, SIGKILL) != 0)
- DPLOG(ERROR) << "Sending SIGKILL to process " << pid << " failed";
-
- child->sent_sigkill = true;
- }
- return false;
-}
-
-void Zygote::ReapChildren() {
- base::TimeTicks now = base::TimeTicks::Now();
- std::vector<ZygoteProcessInfo>::iterator it = to_reap_.begin();
- while (it != to_reap_.end()) {
- if (ReapChild(now, &(*it))) {
- it = to_reap_.erase(it);
- } else {
- it++;
- }
- }
-}
-
-bool Zygote::GetProcessInfo(base::ProcessHandle pid,
- ZygoteProcessInfo* process_info) {
- DCHECK(process_info);
- const ZygoteProcessMap::const_iterator it = process_info_map_.find(pid);
- if (it == process_info_map_.end()) {
- return false;
- }
- *process_info = it->second;
- return true;
-}
-
-bool Zygote::UsingSUIDSandbox() const {
- return sandbox_flags_ & service_manager::SandboxLinux::kSUID;
-}
-
-bool Zygote::UsingNSSandbox() const {
- return sandbox_flags_ & service_manager::SandboxLinux::kUserNS;
-}
-
-bool Zygote::HandleRequestFromBrowser(int fd) {
- std::vector<base::ScopedFD> fds;
- char buf[kZygoteMaxMessageLength];
- const ssize_t len =
- base::UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds);
-
- if (len == 0 || (len == -1 && errno == ECONNRESET)) {
- // EOF from the browser. We should die.
- // TODO(eugenis): call __sanititizer_cov_dump() here to obtain code
- // coverage for the Zygote. Currently it's not possible because of
- // confusion over who is responsible for closing the file descriptor.
- _exit(0);
- return false;
- }
-
- if (len == -1) {
- PLOG(ERROR) << "Error reading message from browser";
- return false;
- }
-
- base::Pickle pickle(buf, len);
- base::PickleIterator iter(pickle);
-
- int kind;
- if (iter.ReadInt(&kind)) {
- switch (kind) {
- case kZygoteCommandFork:
- // This function call can return multiple times, once per fork().
- return HandleForkRequest(fd, iter, std::move(fds));
-
- case kZygoteCommandReap:
- if (!fds.empty())
- break;
- HandleReapRequest(fd, iter);
- return false;
- case kZygoteCommandGetTerminationStatus:
- if (!fds.empty())
- break;
- HandleGetTerminationStatus(fd, iter);
- return false;
- case kZygoteCommandGetSandboxStatus:
- HandleGetSandboxStatus(fd, iter);
- return false;
- case kZygoteCommandForkRealPID:
- // This shouldn't happen in practice, but some failure paths in
- // HandleForkRequest (e.g., if ReadArgsAndFork fails during depickling)
- // could leave this command pending on the socket.
- LOG(ERROR) << "Unexpected real PID message from browser";
- NOTREACHED();
- return false;
- default:
- NOTREACHED();
- break;
- }
- }
-
- LOG(WARNING) << "Error parsing message from browser";
- return false;
-}
-
-void Zygote::HandleReapRequest(int fd, base::PickleIterator iter) {
- base::ProcessId child;
-
- if (!iter.ReadInt(&child)) {
- LOG(WARNING) << "Error parsing reap request from browser";
- return;
- }
-
- ZygoteProcessInfo child_info;
- if (!GetProcessInfo(child, &child_info)) {
- LOG(ERROR) << "Child not found!";
- NOTREACHED();
- return;
- }
- child_info.time_of_reap_request = base::TimeTicks::Now();
-
- if (!child_info.started_from_helper) {
- to_reap_.push_back(child_info);
- } else {
- // For processes from the helper, send a GetTerminationStatus request
- // with known_dead set to true.
- // This is not perfect, as the process may be killed instantly, but is
- // better than ignoring the request.
- base::TerminationStatus status;
- int exit_code;
- bool got_termination_status =
- GetTerminationStatus(child, true /* known_dead */, &status, &exit_code);
- DCHECK(got_termination_status);
- }
- process_info_map_.erase(child);
-}
-
-bool Zygote::GetTerminationStatus(base::ProcessHandle real_pid,
- bool known_dead,
- base::TerminationStatus* status,
- int* exit_code) {
- ZygoteProcessInfo child_info;
- if (!GetProcessInfo(real_pid, &child_info)) {
- LOG(ERROR) << "Zygote::GetTerminationStatus for unknown PID " << real_pid;
- NOTREACHED();
- return false;
- }
- // We know about |real_pid|.
- const base::ProcessHandle child = child_info.internal_pid;
- if (child_info.started_from_helper) {
- if (!child_info.started_from_helper->GetTerminationStatus(
- child, known_dead, status, exit_code)) {
- return false;
- }
- } else {
- // Handle the request directly.
- if (known_dead) {
- *status = base::GetKnownDeadTerminationStatus(child, exit_code);
- } else {
- // We don't know if the process is dying, so get its status but don't
- // wait.
- *status = base::GetTerminationStatus(child, exit_code);
- }
- }
- // Successfully got a status for |real_pid|.
- if (*status != base::TERMINATION_STATUS_STILL_RUNNING) {
- // Time to forget about this process.
- process_info_map_.erase(real_pid);
- }
-
- if (WIFEXITED(*exit_code)) {
- const int exit_status = WEXITSTATUS(*exit_code);
- if (exit_status == sandbox::NamespaceSandbox::SignalExitCode(SIGINT) ||
- exit_status == sandbox::NamespaceSandbox::SignalExitCode(SIGTERM)) {
- *status = base::TERMINATION_STATUS_PROCESS_WAS_KILLED;
- }
- }
-
- return true;
-}
-
-void Zygote::HandleGetTerminationStatus(int fd, base::PickleIterator iter) {
- bool known_dead;
- base::ProcessHandle child_requested;
-
- if (!iter.ReadBool(&known_dead) || !iter.ReadInt(&child_requested)) {
- LOG(WARNING) << "Error parsing GetTerminationStatus request "
- << "from browser";
- return;
- }
-
- base::TerminationStatus status;
- int exit_code;
-
- bool got_termination_status =
- GetTerminationStatus(child_requested, known_dead, &status, &exit_code);
- if (!got_termination_status) {
- // Assume that if we can't find the child in the sandbox, then
- // it terminated normally.
- NOTREACHED();
- status = base::TERMINATION_STATUS_NORMAL_TERMINATION;
- exit_code = service_manager::RESULT_CODE_NORMAL_EXIT;
- }
-
- base::Pickle write_pickle;
- write_pickle.WriteInt(static_cast<int>(status));
- write_pickle.WriteInt(exit_code);
- ssize_t written =
- HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size()));
- if (written != static_cast<ssize_t>(write_pickle.size()))
- PLOG(ERROR) << "write";
-}
-
-int Zygote::ForkWithRealPid(const std::string& process_type,
- const base::GlobalDescriptors::Mapping& fd_mapping,
- const std::string& channel_id,
- base::ScopedFD pid_oracle,
- std::string* uma_name,
- int* uma_sample,
- int* uma_boundary_value) {
- ZygoteForkDelegate* helper = nullptr;
- for (auto i = helpers_.begin(); i != helpers_.end(); ++i) {
- if ((*i)->CanHelp(process_type, uma_name, uma_sample, uma_boundary_value)) {
- helper = i->get();
- break;
- }
- }
-
- base::ScopedFD read_pipe, write_pipe;
- base::ProcessId pid = 0;
- if (helper) {
- int mojo_channel_fd = LookUpFd(fd_mapping, kMojoIPCChannel);
- if (mojo_channel_fd < 0) {
- DLOG(ERROR) << "Failed to find kMojoIPCChannel in FD mapping";
- return -1;
- }
- std::vector<int> fds;
- fds.push_back(mojo_channel_fd); // kBrowserFDIndex
- fds.push_back(pid_oracle.get()); // kPIDOracleFDIndex
- pid = helper->Fork(process_type, fds, channel_id);
-
- // Helpers should never return in the child process.
- CHECK_NE(pid, 0);
- } else {
- PCHECK(base::CreatePipe(&read_pipe, &write_pipe));
- if (sandbox_flags_ & service_manager::SandboxLinux::kPIDNS &&
- sandbox_flags_ & service_manager::SandboxLinux::kUserNS) {
- pid = sandbox::NamespaceSandbox::ForkInNewPidNamespace(
- /*drop_capabilities_in_child=*/true);
- } else {
- pid = sandbox::Credentials::ForkAndDropCapabilitiesInChild();
- }
- }
-
- if (pid == 0) {
- // In the child process.
-
- // If the process is the init process inside a PID namespace, it must have
- // explicit signal handlers.
- if (getpid() == 1) {
- static const int kTerminationSignals[] = {
- SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGABRT, SIGPIPE, SIGUSR1, SIGUSR2};
- for (const int sig : kTerminationSignals) {
- sandbox::NamespaceSandbox::InstallTerminationSignalHandler(
- sig, sandbox::NamespaceSandbox::SignalExitCode(sig));
- }
- }
-
- write_pipe.reset();
-
- // Ping the PID oracle socket so the browser can find our PID.
- CHECK(SendZygoteChildPing(pid_oracle.get()));
-
- // Now read back our real PID from the zygote.
- base::ProcessId real_pid;
- if (!base::ReadFromFD(read_pipe.get(), reinterpret_cast<char*>(&real_pid),
- sizeof(real_pid))) {
- LOG(FATAL) << "Failed to synchronise with parent zygote process";
- }
- if (real_pid <= 0) {
- LOG(FATAL) << "Invalid pid from parent zygote";
- }
- // Sandboxed processes need to send the global, non-namespaced PID when
- // setting up an IPC channel to their parent.
- IPC::Channel::SetGlobalPid(real_pid);
- // Force the real PID so chrome event data have a PID that corresponds
- // to system trace event data.
- base::trace_event::TraceLog::GetInstance()->SetProcessID(
- static_cast<int>(real_pid));
- base::InitUniqueIdForProcessInPidNamespace(real_pid);
- return 0;
- }
-
- // In the parent process.
- if (pid < 0) {
- // Fork failed.
- return -1;
- }
-
- read_pipe.reset();
- pid_oracle.reset();
-
- // Always receive a real PID from the zygote host, though it might
- // be invalid (see below).
- base::ProcessId real_pid = -1;
- {
- std::vector<base::ScopedFD> recv_fds;
- char buf[kZygoteMaxMessageLength];
- const ssize_t len = base::UnixDomainSocket::RecvMsg(
- kZygoteSocketPairFd, buf, sizeof(buf), &recv_fds);
-
- if (len > 0) {
- CHECK(recv_fds.empty());
-
- base::Pickle pickle(buf, len);
- base::PickleIterator iter(pickle);
-
- int kind;
- CHECK(iter.ReadInt(&kind));
- CHECK(kind == kZygoteCommandForkRealPID);
- CHECK(iter.ReadInt(&real_pid));
- }
- }
-
- // If we successfully forked a child, but it crashed without sending
- // a message to the browser, the browser won't have found its PID.
- if (real_pid < 0) {
- KillAndReap(pid, helper);
- return -1;
- }
-
- // If we're not using a helper, send the PID back to the child process.
- if (!helper) {
- ssize_t written =
- HANDLE_EINTR(write(write_pipe.get(), &real_pid, sizeof(real_pid)));
- if (written != sizeof(real_pid)) {
- KillAndReap(pid, helper);
- return -1;
- }
- }
-
- // Now set-up this process to be tracked by the Zygote.
- if (process_info_map_.find(real_pid) != process_info_map_.end()) {
- LOG(ERROR) << "Already tracking PID " << real_pid;
- NOTREACHED();
- }
- process_info_map_[real_pid].internal_pid = pid;
- process_info_map_[real_pid].started_from_helper = helper;
-
- return real_pid;
-}
-
-base::ProcessId Zygote::ReadArgsAndFork(base::PickleIterator iter,
- std::vector<base::ScopedFD> fds,
- std::string* uma_name,
- int* uma_sample,
- int* uma_boundary_value) {
- std::vector<std::string> args;
- int argc = 0;
- int numfds = 0;
- base::GlobalDescriptors::Mapping mapping;
- std::string process_type;
- std::string channel_id;
- const std::string channel_id_prefix =
- std::string("--") +
- service_manager::switches::kServiceRequestChannelToken + std::string("=");
-
- if (!iter.ReadString(&process_type))
- return -1;
- if (!iter.ReadInt(&argc))
- return -1;
-
- for (int i = 0; i < argc; ++i) {
- std::string arg;
- if (!iter.ReadString(&arg))
- return -1;
- args.push_back(arg);
- if (arg.compare(0, channel_id_prefix.length(), channel_id_prefix) == 0)
- channel_id = arg.substr(channel_id_prefix.length());
- }
-
- // timezone_id is obtained from ICU in zygote host so that it can't be
- // invalid. For an unknown reason, if an invalid ID is passed down here, the
- // worst result would be that timezone would be set to Etc/Unknown.
- base::string16 timezone_id;
- if (!iter.ReadString16(&timezone_id))
- return -1;
- icu::TimeZone::adoptDefault(icu::TimeZone::createTimeZone(
- icu::UnicodeString(FALSE, timezone_id.data(), timezone_id.length())));
-
- if (!iter.ReadInt(&numfds))
- return -1;
- if (numfds != static_cast<int>(fds.size()))
- return -1;
-
- // First FD is the PID oracle socket.
- if (fds.size() < 1)
- return -1;
- base::ScopedFD pid_oracle(std::move(fds[0]));
-
- // Remaining FDs are for the global descriptor mapping.
- for (int i = 1; i < numfds; ++i) {
- base::GlobalDescriptors::Key key;
- if (!iter.ReadUInt32(&key))
- return -1;
- mapping.push_back(base::GlobalDescriptors::Descriptor(key, fds[i].get()));
- }
-
- mapping.push_back(ipc_backchannel_);
-
- // Returns twice, once per process.
- base::ProcessId child_pid =
- ForkWithRealPid(process_type, mapping, channel_id, std::move(pid_oracle),
- uma_name, uma_sample, uma_boundary_value);
- if (!child_pid) {
- // This is the child process.
-
- // Our socket from the browser.
- PCHECK(0 == IGNORE_EINTR(close(kZygoteSocketPairFd)));
-
- // Pass ownership of file descriptors from fds to GlobalDescriptors.
- for (base::ScopedFD& fd : fds)
- ignore_result(fd.release());
- base::GlobalDescriptors::GetInstance()->Reset(mapping);
-
- // Reset the process-wide command line to our new command line.
- base::CommandLine::Reset();
- base::CommandLine::Init(0, nullptr);
- base::CommandLine::ForCurrentProcess()->InitFromArgv(args);
-
- // Update the process title. The argv was already cached by the call to
- // SetProcessTitleFromCommandLine in ChromeMain, so we can pass NULL here
- // (we don't have the original argv at this point).
- service_manager::SetProcessTitleFromCommandLine(nullptr);
- } else if (child_pid < 0) {
- LOG(ERROR) << "Zygote could not fork: process_type " << process_type
- << " numfds " << numfds << " child_pid " << child_pid;
- }
- return child_pid;
-}
-
-bool Zygote::HandleForkRequest(int fd,
- base::PickleIterator iter,
- std::vector<base::ScopedFD> fds) {
- std::string uma_name;
- int uma_sample;
- int uma_boundary_value;
- base::ProcessId child_pid = ReadArgsAndFork(iter, std::move(fds), &uma_name,
- &uma_sample, &uma_boundary_value);
- if (child_pid == 0)
- return true;
- // If there's no UMA report for this particular fork, then check if any
- // helpers have an initial UMA report for us to send instead.
- while (uma_name.empty() && initial_uma_index_ < helpers_.size()) {
- helpers_[initial_uma_index_++]->InitialUMA(&uma_name, &uma_sample,
- &uma_boundary_value);
- }
- // Must always send reply, as ZygoteHost blocks while waiting for it.
- base::Pickle reply_pickle;
- reply_pickle.WriteInt(child_pid);
- reply_pickle.WriteString(uma_name);
- if (!uma_name.empty()) {
- reply_pickle.WriteInt(uma_sample);
- reply_pickle.WriteInt(uma_boundary_value);
- }
- if (HANDLE_EINTR(write(fd, reply_pickle.data(), reply_pickle.size())) !=
- static_cast<ssize_t>(reply_pickle.size()))
- PLOG(ERROR) << "write";
- return false;
-}
-
-bool Zygote::HandleGetSandboxStatus(int fd, base::PickleIterator iter) {
- if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) !=
- sizeof(sandbox_flags_)) {
- PLOG(ERROR) << "write";
- }
-
- return false;
-}
-
-} // namespace service_manager
diff --git a/chromium/services/service_manager/zygote/zygote_linux.h b/chromium/services/service_manager/zygote/zygote_linux.h
deleted file mode 100644
index 840aa17a093..00000000000
--- a/chromium/services/service_manager/zygote/zygote_linux.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2012 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 SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_LINUX_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_LINUX_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/containers/small_map.h"
-#include "base/files/scoped_file.h"
-#include "base/posix/global_descriptors.h"
-#include "base/process/kill.h"
-#include "base/process/process.h"
-#include "base/process/process_handle.h"
-#include "base/time/time.h"
-
-namespace base {
-class PickleIterator;
-}
-
-namespace service_manager {
-
-class ZygoteForkDelegate;
-
-// This is the object which implements the zygote. The ZygoteMain function,
-// which is called from ChromeMain, simply constructs one of these objects and
-// runs it.
-class Zygote {
- public:
- Zygote(int sandbox_flags,
- std::vector<std::unique_ptr<ZygoteForkDelegate>> helpers,
- const base::GlobalDescriptors::Descriptor& ipc_backchannel);
- ~Zygote();
-
- bool ProcessRequests();
-
- private:
- struct ZygoteProcessInfo {
- // Pid from inside the Zygote's PID namespace.
- base::ProcessHandle internal_pid;
- // Keeps track of which fork delegate helper the process was started from.
- ZygoteForkDelegate* started_from_helper;
- // Records when the browser requested the zygote to reap this process.
- base::TimeTicks time_of_reap_request;
- // Notes whether the zygote has sent SIGKILL to this process.
- bool sent_sigkill;
- };
- using ZygoteProcessMap =
- base::small_map<std::map<base::ProcessHandle, ZygoteProcessInfo>>;
-
- // Retrieve a ZygoteProcessInfo from the process_info_map_.
- // Returns true and write to process_info if |pid| can be found, return
- // false otherwise.
- bool GetProcessInfo(base::ProcessHandle pid, ZygoteProcessInfo* process_info);
-
- // Returns true if the SUID sandbox is active.
- bool UsingSUIDSandbox() const;
- // Returns true if the NS sandbox is active.
- bool UsingNSSandbox() const;
-
- // ---------------------------------------------------------------------------
- // Requests from the browser...
-
- // Read and process a request from the browser. Returns true if we are in a
- // new process and thus need to unwind back into ChromeMain.
- bool HandleRequestFromBrowser(int fd);
-
- void HandleReapRequest(int fd, base::PickleIterator iter);
-
- // Get the termination status of |real_pid|. |real_pid| is the PID as it
- // appears outside of the sandbox.
- // Return true if it managed to get the termination status and return the
- // status in |status| and the exit code in |exit_code|.
- bool GetTerminationStatus(base::ProcessHandle real_pid,
- bool known_dead,
- base::TerminationStatus* status,
- int* exit_code);
-
- void HandleGetTerminationStatus(int fd, base::PickleIterator iter);
-
- // This is equivalent to fork(), except that, when using the SUID sandbox, it
- // returns the real PID of the child process as it appears outside the
- // sandbox, rather than returning the PID inside the sandbox. The child's
- // real PID is determined by having it call
- // service_manager::SendZygoteChildPing(int) using the |pid_oracle|
- // descriptor.
- // Finally, when using a ZygoteForkDelegate helper, |uma_name|, |uma_sample|,
- // and |uma_boundary_value| may be set if the helper wants to make a UMA
- // report via UMA_HISTOGRAM_ENUMERATION.
- int ForkWithRealPid(const std::string& process_type,
- const base::GlobalDescriptors::Mapping& fd_mapping,
- const std::string& channel_id,
- base::ScopedFD pid_oracle,
- std::string* uma_name,
- int* uma_sample,
- int* uma_boundary_value);
-
- // Unpacks process type and arguments from |iter| and forks a new process.
- // Returns -1 on error, otherwise returns twice, returning 0 to the child
- // process and the child process ID to the parent process, like fork().
- base::ProcessId ReadArgsAndFork(base::PickleIterator iter,
- std::vector<base::ScopedFD> fds,
- std::string* uma_name,
- int* uma_sample,
- int* uma_boundary_value);
-
- // Handle a 'fork' request from the browser: this means that the browser
- // wishes to start a new renderer. Returns true if we are in a new process,
- // otherwise writes the child_pid back to the browser via |fd|. Writes a
- // child_pid of -1 on error.
- bool HandleForkRequest(int fd,
- base::PickleIterator iter,
- std::vector<base::ScopedFD> fds);
-
- bool HandleGetSandboxStatus(int fd, base::PickleIterator iter);
-
- // Attempt to reap the child process by calling waitpid, and return
- // whether successful. If the process has not terminated within
- // 2 seconds of its reap request, send it SIGKILL.
- bool ReapChild(const base::TimeTicks& now, ZygoteProcessInfo* child);
-
- // Attempt to reap all outstanding children in |to_reap_|.
- void ReapChildren();
-
- // The Zygote needs to keep some information about each process. Most
- // notably what the PID of the process is inside the PID namespace of
- // the Zygote and whether or not a process was started by the
- // ZygoteForkDelegate helper.
- ZygoteProcessMap process_info_map_;
-
- const int sandbox_flags_;
- std::vector<std::unique_ptr<ZygoteForkDelegate>> helpers_;
-
- // Count of how many fork delegates for which we've invoked InitialUMA().
- size_t initial_uma_index_;
-
- // The vector contains the child processes that need to be reaped.
- std::vector<ZygoteProcessInfo> to_reap_;
-
- // Sandbox IPC channel for renderers to invoke services from the browser. See
- // https://chromium.googlesource.com/chromium/src/+/master/docs/linux/sandbox_ipc.md
- base::GlobalDescriptors::Descriptor ipc_backchannel_;
-};
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_LINUX_H_
diff --git a/chromium/services/service_manager/zygote/zygote_main.h b/chromium/services/service_manager/zygote/zygote_main.h
deleted file mode 100644
index 8de1e6abc32..00000000000
--- a/chromium/services/service_manager/zygote/zygote_main.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2013 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 SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_MAIN_H_
-#define SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_MAIN_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/component_export.h"
-#include "build/build_config.h"
-
-namespace service_manager {
-
-class ZygoteForkDelegate;
-
-// |delegate| must outlive this call.
-COMPONENT_EXPORT(SERVICE_MANAGER_ZYGOTE)
-bool ZygoteMain(
- std::vector<std::unique_ptr<ZygoteForkDelegate>> fork_delegates);
-
-} // namespace service_manager
-
-#endif // SERVICES_SERVICE_MANAGER_ZYGOTE_ZYGOTE_MAIN_H_
diff --git a/chromium/services/service_manager/zygote/zygote_main_linux.cc b/chromium/services/service_manager/zygote/zygote_main_linux.cc
deleted file mode 100644
index cf9ec082e69..00000000000
--- a/chromium/services/service_manager/zygote/zygote_main_linux.cc
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright (c) 2012 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 "services/service_manager/zygote/zygote_main.h"
-
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/posix/unix_domain_socket.h"
-#include "base/rand_util.h"
-#include "base/strings/safe_sprintf.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/system/sys_info.h"
-#include "build/build_config.h"
-#include "sandbox/linux/services/credentials.h"
-#include "sandbox/linux/services/init_process_reaper.h"
-#include "sandbox/linux/services/libc_interceptor.h"
-#include "sandbox/linux/services/namespace_sandbox.h"
-#include "sandbox/linux/services/thread_helpers.h"
-#include "sandbox/linux/suid/client/setuid_sandbox_client.h"
-#include "services/service_manager/embedder/descriptors.h"
-#include "services/service_manager/embedder/switches.h"
-#include "services/service_manager/sandbox/linux/sandbox_debug_handling_linux.h"
-#include "services/service_manager/sandbox/linux/sandbox_linux.h"
-#include "services/service_manager/sandbox/sandbox.h"
-#include "services/service_manager/sandbox/switches.h"
-#include "services/service_manager/zygote/common/common_sandbox_support_linux.h"
-#include "services/service_manager/zygote/common/zygote_commands_linux.h"
-#include "services/service_manager/zygote/common/zygote_fork_delegate_linux.h"
-#include "services/service_manager/zygote/zygote_linux.h"
-#include "third_party/icu/source/i18n/unicode/timezone.h"
-
-namespace service_manager {
-
-namespace {
-
-void CloseFds(const std::vector<int>& fds) {
- for (const auto& it : fds) {
- PCHECK(0 == IGNORE_EINTR(close(it)));
- }
-}
-
-base::OnceClosure ClosureFromTwoClosures(base::OnceClosure one,
- base::OnceClosure two) {
- return base::BindOnce(
- [](base::OnceClosure one, base::OnceClosure two) {
- if (!one.is_null())
- std::move(one).Run();
- if (!two.is_null())
- std::move(two).Run();
- },
- std::move(one), std::move(two));
-}
-
-} // namespace
-
-// This function triggers the static and lazy construction of objects that need
-// to be created before imposing the sandbox.
-static void ZygotePreSandboxInit() {
- base::RandUint64();
-
- base::SysInfo::AmountOfPhysicalMemory();
- base::SysInfo::NumberOfProcessors();
-
- // ICU DateFormat class (used in base/time_format.cc) needs to get the
- // Olson timezone ID by accessing the zoneinfo files on disk. After
- // TimeZone::createDefault is called once here, the timezone ID is
- // cached and there's no more need to access the file system.
- std::unique_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault());
-}
-
-static bool CreateInitProcessReaper(
- base::OnceClosure post_fork_parent_callback) {
- // The current process becomes init(1), this function returns from a
- // newly created process.
- if (!sandbox::CreateInitProcessReaper(std::move(post_fork_parent_callback))) {
- LOG(ERROR) << "Error creating an init process to reap zombies";
- return false;
- }
- return true;
-}
-
-// Enter the setuid sandbox. This requires the current process to have been
-// created through the setuid sandbox.
-static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox,
- base::OnceClosure post_fork_parent_callback) {
- DCHECK(setuid_sandbox);
- DCHECK(setuid_sandbox->IsSuidSandboxChild());
-
- // Use the SUID sandbox. This still allows the seccomp sandbox to
- // be enabled by the process later.
-
- if (!setuid_sandbox->IsSuidSandboxUpToDate()) {
- LOG(WARNING) << "You are using a wrong version of the setuid binary!\n"
- "Please read "
- "https://chromium.googlesource.com/chromium/src/+/master/"
- "docs/linux/suid_sandbox_development.md."
- "\n\n";
- }
-
- if (!setuid_sandbox->ChrootMe())
- return false;
-
- if (setuid_sandbox->IsInNewPIDNamespace()) {
- CHECK_EQ(1, getpid())
- << "The SUID sandbox created a new PID namespace but Zygote "
- "is not the init process. Please, make sure the SUID "
- "binary is up to date.";
- }
-
- if (getpid() == 1) {
- // The setuid sandbox has created a new PID namespace and we need
- // to assume the role of init.
- CHECK(CreateInitProcessReaper(std::move(post_fork_parent_callback)));
- }
-
- CHECK(service_manager::SandboxDebugHandling::SetDumpableStatusAndHandlers());
- return true;
-}
-
-static void DropAllCapabilities(int proc_fd) {
- CHECK(sandbox::Credentials::DropAllCapabilities(proc_fd));
-}
-
-static void EnterNamespaceSandbox(service_manager::SandboxLinux* linux_sandbox,
- base::OnceClosure post_fork_parent_callback) {
- linux_sandbox->EngageNamespaceSandbox(true /* from_zygote */);
- if (getpid() == 1) {
- CHECK(CreateInitProcessReaper(ClosureFromTwoClosures(
- base::BindOnce(DropAllCapabilities, linux_sandbox->proc_fd()),
- std::move(post_fork_parent_callback))));
- }
-}
-
-static void EnterLayerOneSandbox(service_manager::SandboxLinux* linux_sandbox,
- const bool using_layer1_sandbox,
- base::OnceClosure post_fork_parent_callback) {
- DCHECK(linux_sandbox);
-
- ZygotePreSandboxInit();
-
-// Check that the pre-sandbox initialization didn't spawn threads.
-// It's not just our code which may do so - some system-installed libraries
-// are known to be culprits, e.g. lttng.
-#if !defined(THREAD_SANITIZER)
- CHECK(sandbox::ThreadHelpers::IsSingleThreaded());
-#endif
-
- sandbox::SetuidSandboxClient* setuid_sandbox =
- linux_sandbox->setuid_sandbox_client();
- if (setuid_sandbox->IsSuidSandboxChild()) {
- CHECK(
- EnterSuidSandbox(setuid_sandbox, std::move(post_fork_parent_callback)))
- << "Failed to enter setuid sandbox";
- } else if (sandbox::NamespaceSandbox::InNewUserNamespace()) {
- EnterNamespaceSandbox(linux_sandbox, std::move(post_fork_parent_callback));
- } else {
- CHECK(!using_layer1_sandbox);
- }
-}
-
-bool ZygoteMain(
- std::vector<std::unique_ptr<ZygoteForkDelegate>> fork_delegates) {
- sandbox::SetAmZygoteOrRenderer(true, GetSandboxFD());
-
- auto* linux_sandbox = service_manager::SandboxLinux::GetInstance();
-
- // Skip pre-initializing sandbox when sandbox is disabled for
- // https://crbug.com/444900.
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- service_manager::switches::kNoSandbox) &&
- !base::CommandLine::ForCurrentProcess()->HasSwitch(
- service_manager::switches::kNoZygoteSandbox)) {
- // This will pre-initialize the various sandboxes that need it.
- linux_sandbox->PreinitializeSandbox();
- }
-
- const bool using_setuid_sandbox =
- linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild();
- const bool using_namespace_sandbox =
- sandbox::NamespaceSandbox::InNewUserNamespace();
- const bool using_layer1_sandbox =
- using_setuid_sandbox || using_namespace_sandbox;
-
- if (using_setuid_sandbox) {
- linux_sandbox->setuid_sandbox_client()->CloseDummyFile();
- }
-
- if (using_layer1_sandbox) {
- // Let the ZygoteHost know we're booting up.
- if (!base::UnixDomainSocket::SendMsg(
- kZygoteSocketPairFd, kZygoteBootMessage, sizeof(kZygoteBootMessage),
- std::vector<int>())) {
- // This is not a CHECK failure because the browser process could either
- // crash or quickly exit while the zygote is starting. In either case a
- // zygote crash is not useful. https://crbug.com/692227
- PLOG(ERROR) << "Failed sending zygote boot message";
- _exit(1);
- }
- }
-
- VLOG(1) << "ZygoteMain: initializing " << fork_delegates.size()
- << " fork delegates";
- for (const auto& fork_delegate : fork_delegates) {
- fork_delegate->Init(GetSandboxFD(), using_layer1_sandbox);
- }
-
- // Turn on the first layer of the sandbox if the configuration warrants it.
- EnterLayerOneSandbox(
- linux_sandbox, using_layer1_sandbox,
- base::BindOnce(CloseFds, linux_sandbox->GetFileDescriptorsToClose()));
-
- const int sandbox_flags = linux_sandbox->GetStatus();
- const bool setuid_sandbox_engaged =
- !!(sandbox_flags & service_manager::SandboxLinux::kSUID);
- CHECK_EQ(using_setuid_sandbox, setuid_sandbox_engaged);
-
- const bool namespace_sandbox_engaged =
- !!(sandbox_flags & service_manager::SandboxLinux::kUserNS);
- CHECK_EQ(using_namespace_sandbox, namespace_sandbox_engaged);
-
- Zygote zygote(sandbox_flags, std::move(fork_delegates),
- base::GlobalDescriptors::Descriptor(
- static_cast<uint32_t>(kSandboxIPCChannel), GetSandboxFD()));
-
- // This function call can return multiple times, once per fork().
- return zygote.ProcessRequests();
-}
-
-} // namespace service_manager