summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/ui/webui/sandbox
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/browser/ui/webui/sandbox')
-rw-r--r--chromium/chrome/browser/ui/webui/sandbox/OWNERS3
-rw-r--r--chromium/chrome/browser/ui/webui/sandbox/sandbox_handler.cc134
-rw-r--r--chromium/chrome/browser/ui/webui/sandbox/sandbox_handler.h52
-rw-r--r--chromium/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc104
-rw-r--r--chromium/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h31
5 files changed, 324 insertions, 0 deletions
diff --git a/chromium/chrome/browser/ui/webui/sandbox/OWNERS b/chromium/chrome/browser/ui/webui/sandbox/OWNERS
new file mode 100644
index 00000000000..058ee25caec
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/sandbox/OWNERS
@@ -0,0 +1,3 @@
+file://sandbox/OWNERS
+# COMPONENT: Internals>Sandbox
+# TEAM: security-dev@chromium.org
diff --git a/chromium/chrome/browser/ui/webui/sandbox/sandbox_handler.cc b/chromium/chrome/browser/ui/webui/sandbox/sandbox_handler.cc
new file mode 100644
index 00000000000..a4f1c53905c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/sandbox/sandbox_handler.cc
@@ -0,0 +1,134 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/sandbox/sandbox_handler.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/task/post_task.h"
+#include "base/values.h"
+#include "content/public/browser/browser_child_process_host_iterator.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/child_process_data.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/common/process_type.h"
+#include "services/service_manager/sandbox/win/sandbox_win.h"
+
+using content::BrowserChildProcessHostIterator;
+using content::ChildProcessData;
+using content::RenderProcessHost;
+
+namespace sandbox_handler {
+namespace {
+base::Value FetchBrowserChildProcesses() {
+ // The |BrowserChildProcessHostIterator| must only be used on the IO thread.
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ base::Value browser_processes(base::Value::Type::LIST);
+
+ for (BrowserChildProcessHostIterator itr; !itr.Done(); ++itr) {
+ const ChildProcessData& process_data = itr.GetData();
+ // Only add processes that have already started, i.e. with valid handles.
+ if (!process_data.GetProcess().IsValid())
+ continue;
+ base::Value proc(base::Value::Type::DICTIONARY);
+ proc.SetPath("processId", base::Value(base::strict_cast<double>(
+ process_data.GetProcess().Pid())));
+ proc.SetPath("processType",
+ base::Value(content::GetProcessTypeNameInEnglish(
+ process_data.process_type)));
+ proc.SetPath("name", base::Value(process_data.name));
+ proc.SetPath("metricsName", base::Value(process_data.metrics_name));
+ browser_processes.GetList().push_back(std::move(proc));
+ }
+
+ return browser_processes;
+}
+
+base::Value FetchRenderHostProcesses() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ base::Value renderer_processes(base::Value::Type::LIST);
+
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ RenderProcessHost* host = it.GetCurrentValue();
+ // Skip processes that might not have started yet.
+ if (!host->GetProcess().IsValid())
+ continue;
+
+ base::Value proc(base::Value::Type::DICTIONARY);
+ proc.SetPath(
+ "processId",
+ base::Value(base::strict_cast<double>(host->GetProcess().Pid())));
+ renderer_processes.GetList().push_back(std::move(proc));
+ }
+
+ return renderer_processes;
+}
+
+} // namespace
+
+SandboxHandler::SandboxHandler() = default;
+SandboxHandler::~SandboxHandler() = default;
+
+void SandboxHandler::RegisterMessages() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ web_ui()->RegisterMessageCallback(
+ "requestSandboxDiagnostics",
+ base::BindRepeating(&SandboxHandler::HandleRequestSandboxDiagnostics,
+ base::Unretained(this)));
+}
+
+void SandboxHandler::HandleRequestSandboxDiagnostics(
+ const base::ListValue* args) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ CHECK_EQ(1U, args->GetList().size());
+ sandbox_diagnostics_callback_id_ = args->GetList()[0].Clone();
+
+ AllowJavascript();
+
+ base::PostTaskAndReplyWithResult(
+ FROM_HERE, {content::BrowserThread::IO},
+ base::Bind(&FetchBrowserChildProcesses),
+ base::Bind(&SandboxHandler::FetchBrowserChildProcessesCompleted,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void SandboxHandler::FetchBrowserChildProcessesCompleted(
+ base::Value browser_processes) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ browser_processes_ = std::move(browser_processes);
+
+ service_manager::SandboxWin::GetPolicyDiagnostics(
+ base::Bind(&SandboxHandler::FetchSandboxDiagnosticsCompleted,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+// This runs nested inside SandboxWin so we get out quickly.
+void SandboxHandler::FetchSandboxDiagnosticsCompleted(
+ base::Value sandbox_policies) {
+ sandbox_policies_ = std::move(sandbox_policies);
+ base::PostTask(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&SandboxHandler::GetRendererProcessesAndFinish,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void SandboxHandler::GetRendererProcessesAndFinish() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ auto renderer_processes = FetchRenderHostProcesses();
+ base::Value results(base::Value::Type::DICTIONARY);
+ results.SetPath("browser", std::move(browser_processes_));
+ results.SetPath("policies", std::move(sandbox_policies_));
+ results.SetPath("renderer", std::move(renderer_processes));
+ ResolveJavascriptCallback(sandbox_diagnostics_callback_id_,
+ std::move(results));
+}
+
+} // namespace sandbox_handler
diff --git a/chromium/chrome/browser/ui/webui/sandbox/sandbox_handler.h b/chromium/chrome/browser/ui/webui/sandbox/sandbox_handler.h
new file mode 100644
index 00000000000..822044f28b3
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/sandbox/sandbox_handler.h
@@ -0,0 +1,52 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SANDBOX_SANDBOX_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SANDBOX_SANDBOX_HANDLER_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "content/public/browser/web_ui_message_handler.h"
+
+namespace base {
+class Value;
+class ListValue;
+} // namespace base
+
+namespace sandbox_handler {
+// This class takes care of sending the list of processes and their sandboxing
+// status to the chrome://sandbox WebUI page when it is requested.
+class SandboxHandler : public content::WebUIMessageHandler {
+ public:
+ SandboxHandler();
+ ~SandboxHandler() override;
+
+ private:
+ // content::WebUIMessageHandler:
+ void RegisterMessages() override;
+
+ // Callback for the "requestSandboxDiagnostics" message.
+ void HandleRequestSandboxDiagnostics(const base::ListValue* args);
+
+ void OnSandboxDataFetched(base::Value results);
+
+ void FetchBrowserChildProcessesCompleted(base::Value browser_processes);
+ void FetchSandboxDiagnosticsCompleted(base::Value sandbox_policies);
+ void GetRendererProcessesAndFinish();
+
+ // The ID of the callback that will get invoked with the sandbox list.
+ base::Value sandbox_diagnostics_callback_id_;
+ base::Value browser_processes_;
+ base::Value sandbox_policies_;
+
+ // Always keep this the last member of this class to make sure it's the
+ // first thing to be destructed.
+ base::WeakPtrFactory<SandboxHandler> weak_ptr_factory_{this};
+
+ DISALLOW_COPY_AND_ASSIGN(SandboxHandler);
+};
+
+} // namespace sandbox_handler
+
+#endif // CHROME_BROWSER_UI_WEBUI_SANDBOX_SANDBOX_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc b/chromium/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc
new file mode 100644
index 00000000000..9c3783b3791
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.cc
@@ -0,0 +1,104 @@
+// 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 "chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h"
+
+#include <string>
+
+#include "build/build_config.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/grit/browser_resources.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+#if defined(OS_WIN)
+#include "chrome/browser/ui/webui/sandbox/sandbox_handler.h"
+#endif
+
+#if defined(OS_ANDROID)
+#include "chrome/common/sandbox_status_extension_android.mojom.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#endif
+
+#if defined(OS_LINUX)
+#include "services/service_manager/sandbox/sandbox.h"
+#include "services/service_manager/zygote/zygote_host_linux.h"
+#endif
+
+namespace {
+
+#if defined(OS_LINUX)
+static void SetSandboxStatusData(content::WebUIDataSource* source) {
+ // Get expected sandboxing status of renderers.
+ const int status =
+ service_manager::ZygoteHost::GetInstance()->GetRendererSandboxStatus();
+
+ source->AddBoolean("suid", status & service_manager::SandboxLinux::kSUID);
+ source->AddBoolean("userNs", status & service_manager::SandboxLinux::kUserNS);
+ source->AddBoolean("pidNs", status & service_manager::SandboxLinux::kPIDNS);
+ source->AddBoolean("netNs", status & service_manager::SandboxLinux::kNetNS);
+ source->AddBoolean("seccompBpf",
+ status & service_manager::SandboxLinux::kSeccompBPF);
+ source->AddBoolean("seccompTsync",
+ status & service_manager::SandboxLinux::kSeccompTSYNC);
+ source->AddBoolean("yamaBroker",
+ status & service_manager::SandboxLinux::kYama);
+
+ // Yama does not enforce in user namespaces.
+ bool enforcing_yama_nonbroker =
+ status & service_manager::SandboxLinux::kYama &&
+ !(status & service_manager::SandboxLinux::kUserNS);
+ source->AddBoolean("yamaNonbroker", enforcing_yama_nonbroker);
+
+ // Require either the setuid or namespace sandbox for our first-layer sandbox.
+ bool good_layer1 = (status & service_manager::SandboxLinux::kSUID ||
+ status & service_manager::SandboxLinux::kUserNS) &&
+ status & service_manager::SandboxLinux::kPIDNS &&
+ status & service_manager::SandboxLinux::kNetNS;
+ // A second-layer sandbox is also required to be adequately sandboxed.
+ bool good_layer2 = status & service_manager::SandboxLinux::kSeccompBPF;
+ source->AddBoolean("sandboxGood", good_layer1 && good_layer2);
+}
+#endif
+
+content::WebUIDataSource* CreateDataSource() {
+ content::WebUIDataSource* source =
+ content::WebUIDataSource::Create(chrome::kChromeUISandboxHost);
+ source->SetDefaultResource(IDR_SANDBOX_INTERNALS_HTML);
+ source->AddResourcePath("sandbox_internals.js", IDR_SANDBOX_INTERNALS_JS);
+
+#if defined(OS_LINUX)
+ SetSandboxStatusData(source);
+ source->UseStringsJs();
+#endif
+
+ return source;
+}
+
+} // namespace
+
+SandboxInternalsUI::SandboxInternalsUI(content::WebUI* web_ui)
+ : content::WebUIController(web_ui) {
+#if defined(OS_WIN)
+ web_ui->AddMessageHandler(
+ std::make_unique<sandbox_handler::SandboxHandler>());
+#endif
+ Profile* profile = Profile::FromWebUI(web_ui);
+ content::WebUIDataSource::Add(profile, CreateDataSource());
+}
+
+void SandboxInternalsUI::RenderFrameCreated(
+ content::RenderFrameHost* render_frame_host) {
+#if defined(OS_ANDROID)
+ mojo::AssociatedRemote<chrome::mojom::SandboxStatusExtension> sandbox_status;
+ render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
+ &sandbox_status);
+ sandbox_status->AddSandboxStatusExtension();
+#endif
+}
+
+SandboxInternalsUI::~SandboxInternalsUI() {}
diff --git a/chromium/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h b/chromium/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h
new file mode 100644
index 00000000000..5fbd2ea41f0
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/sandbox/sandbox_internals_ui.h
@@ -0,0 +1,31 @@
+// 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 CHROME_BROWSER_UI_WEBUI_SANDBOX_SANDBOX_INTERNALS_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_SANDBOX_SANDBOX_INTERNALS_UI_H_
+
+#include "base/macros.h"
+#include "content/public/browser/web_ui_controller.h"
+
+// This WebUI page displays the status of the renderer sandbox on Linux and
+// Android. The two OSes share the same basic page, but the data reported are
+// obtained from different places:
+// - On Linux, this object in the browser queries the renderer ZygoteHost
+// to get the sandbox status of the renderers. The data are then specified
+// as loadTimeData on the WebUI Page.
+// - On Android, this object sends an IPC message to the
+// SandboxStatusExtension in the renderer, which installs a JavaScript
+// function on the web page to return the current sandbox status.
+class SandboxInternalsUI : public content::WebUIController {
+ public:
+ explicit SandboxInternalsUI(content::WebUI* web_ui);
+ ~SandboxInternalsUI() override;
+
+ void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SandboxInternalsUI);
+};
+
+#endif // CHROME_BROWSER_UI_WEBUI_SANDBOX_SANDBOX_INTERNALS_UI_H_