From 9db5b3bf338a529d129d9c916310fcd2a92f1981 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Sat, 22 Jun 2019 12:28:28 +0200 Subject: [PATCH] feat: add app.disablePluginSandbox(mimeType) --- docs/api/app.md | 6 + patches/chromium/.patches | 1 + ...ent_ispluginsandboxdisabled_callback.patch | 109 ++++++++++++++++++ shell/browser/api/atom_api_app.cc | 5 + shell/browser/api/atom_api_app.h | 1 + shell/browser/atom_browser_client.cc | 12 ++ shell/browser/atom_browser_client.h | 1 + shell/browser/browser.cc | 4 + shell/browser/browser.h | 10 ++ 9 files changed, 149 insertions(+) create mode 100644 patches/chromium/add_contentbrowserclient_ispluginsandboxdisabled_callback.patch diff --git a/docs/api/app.md b/docs/api/app.md index e4c89982b587a..a6e67446d3229 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -1218,6 +1218,12 @@ Enables full sandbox mode on the app. This method can only be called before app is ready. +### `app.disablePluginSandbox(mimeType)` + +* `mimeType` String + +Disables sandboxing of the ppapi plugin process hosting the plugin identified by mimeType. + ### `app.isInApplicationsFolder()` _macOS_ Returns `Boolean` - Whether the application is currently running from the diff --git a/patches/chromium/.patches b/patches/chromium/.patches index 352b8bf3ef95e..b21446cc76820 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -77,3 +77,4 @@ crashpad_pid_check.patch chore_add_debounce_on_the_updatewebcontentsvisibility_method_to.patch network_service_allow_remote_certificate_verification_logic.patch put_back_deleted_colors_for_autofill.patch +add_contentbrowserclient_ispluginsandboxdisabled_callback.patch diff --git a/patches/chromium/add_contentbrowserclient_ispluginsandboxdisabled_callback.patch b/patches/chromium/add_contentbrowserclient_ispluginsandboxdisabled_callback.patch new file mode 100644 index 0000000000000..d3073a488a698 --- /dev/null +++ b/patches/chromium/add_contentbrowserclient_ispluginsandboxdisabled_callback.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Milan Burda +Date: Sat, 22 Jun 2019 12:23:04 +0200 +Subject: Add ContentBrowserClient::IsPluginSandboxDisabled() callback + +Allows the embedder to decide whether the plugin should be sandboxed. + +diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc +index 2afb96a4c46d654630c5519b7654b42654a88b5f..a56e3419b0ac2dc5b76b982ba494b7cd12ec026f 100644 +--- a/content/browser/ppapi_plugin_process_host.cc ++++ b/content/browser/ppapi_plugin_process_host.cc +@@ -59,10 +59,12 @@ class PpapiPluginSandboxedProcessLauncherDelegate + : public content::SandboxedProcessLauncherDelegate { + public: + PpapiPluginSandboxedProcessLauncherDelegate( ++ bool no_sandbox, + bool is_broker, + const ppapi::PpapiPermissions& permissions) ++ : no_sandbox_(no_sandbox) + #if BUILDFLAG(USE_ZYGOTE_HANDLE) || defined(OS_WIN) +- : is_broker_(is_broker) ++ , is_broker_(is_broker) + #endif + #if defined(OS_WIN) + , +@@ -75,7 +77,7 @@ class PpapiPluginSandboxedProcessLauncherDelegate + + #if defined(OS_WIN) + bool PreSpawnTarget(sandbox::TargetPolicy* policy) override { +- if (is_broker_) ++ if (no_sandbox_ || is_broker_) + return true; + + // The Pepper process is as locked-down as a renderer except that it can +@@ -126,13 +128,15 @@ class PpapiPluginSandboxedProcessLauncherDelegate + } + base::CommandLine::StringType plugin_launcher = browser_command_line + .GetSwitchValueNative(switches::kPpapiPluginLauncher); +- if (is_broker_ || !plugin_launcher.empty()) ++ if (no_sandbox_ || is_broker_ || !plugin_launcher.empty()) + return nullptr; + return service_manager::GetGenericZygote(); + } + #endif // BUILDFLAG(USE_ZYGOTE_HANDLE) + + service_manager::SandboxType GetSandboxType() override { ++ if (no_sandbox_) ++ return service_manager::SANDBOX_TYPE_NO_SANDBOX; + #if defined(OS_WIN) + if (is_broker_) + return service_manager::SANDBOX_TYPE_NO_SANDBOX; +@@ -141,6 +145,7 @@ class PpapiPluginSandboxedProcessLauncherDelegate + } + + private: ++ const bool no_sandbox_; + #if BUILDFLAG(USE_ZYGOTE_HANDLE) || defined(OS_WIN) + const bool is_broker_; + #endif +@@ -438,12 +443,18 @@ bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) { + if (!plugin_launcher.empty()) + cmd_line->PrependWrapper(plugin_launcher); + ++ bool no_sandbox = ++ GetContentClient()->browser()->IsPluginSandboxDisabled(info); ++ if (no_sandbox) { ++ cmd_line->AppendSwitch(service_manager::switches::kNoSandbox); ++ } ++ + // On posix, never use the zygote for the broker. Also, only use the zygote if + // we are not using a plugin launcher - having a plugin launcher means we need + // to use another process instead of just forking the zygote. + process_->Launch( + std::make_unique( +- is_broker_, permissions_), ++ no_sandbox, is_broker_, permissions_), + std::move(cmd_line), true); + return true; + } +diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc +index 2a9661d877fbc09904eb469191523b5cd59eaeda..34ef39acabb1b7211f69b597f4675da25a661ada 100644 +--- a/content/public/browser/content_browser_client.cc ++++ b/content/public/browser/content_browser_client.cc +@@ -650,6 +650,11 @@ bool ContentBrowserClient::IsPluginAllowedToUseDevChannelAPIs( + return false; + } + ++bool ContentBrowserClient::IsPluginSandboxDisabled( ++ const PepperPluginInfo& info) { ++ return false; ++} ++ + bool ContentBrowserClient::BindAssociatedInterfaceRequestFromFrame( + RenderFrameHost* render_frame_host, + const std::string& interface_name, +diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h +index ba27455e1c0934f77ed2871ee585361807ab701a..684b54a555d3bb3eff36cef60fe202bc3f2c11a0 100644 +--- a/content/public/browser/content_browser_client.h ++++ b/content/public/browser/content_browser_client.h +@@ -988,6 +988,9 @@ class CONTENT_EXPORT ContentBrowserClient { + BrowserContext* browser_context, + const GURL& url); + ++ // Allows the embedder to decide whether the plugin should be sandboxed. ++ virtual bool IsPluginSandboxDisabled(const PepperPluginInfo& info); ++ + // Allows to register browser interfaces exposed through the + // RenderProcessHost. Note that interface factory callbacks added to + // |registry| will by default be run immediately on the IO thread, unless a diff --git a/shell/browser/api/atom_api_app.cc b/shell/browser/api/atom_api_app.cc index b4fcced61fd8a..e234975bade3e 100644 --- a/shell/browser/api/atom_api_app.cc +++ b/shell/browser/api/atom_api_app.cc @@ -1295,6 +1295,10 @@ void App::EnableSandbox(mate::Arguments* args) { command_line->AppendSwitch(switches::kEnableSandbox); } +void App::DisablePluginSandbox(const std::string& mime_type) { + Browser::Get()->DisablePluginSandbox(mime_type); +} + void App::SetUserAgentFallback(const std::string& user_agent) { AtomBrowserClient::Get()->SetUserAgent(user_agent); } @@ -1494,6 +1498,7 @@ void App::BuildPrototype(v8::Isolate* isolate, .SetProperty("userAgentFallback", &App::GetUserAgentFallback, &App::SetUserAgentFallback) .SetMethod("enableSandbox", &App::EnableSandbox) + .SetMethod("disablePluginSandbox", &App::DisablePluginSandbox) .SetProperty("allowRendererProcessReuse", &App::CanBrowserClientUseCustomSiteInstance, &App::SetBrowserClientCanUseCustomSiteInstance); diff --git a/shell/browser/api/atom_api_app.h b/shell/browser/api/atom_api_app.h index 89ccf45b31c17..bdef3566233aa 100644 --- a/shell/browser/api/atom_api_app.h +++ b/shell/browser/api/atom_api_app.h @@ -199,6 +199,7 @@ class App : public AtomBrowserClient::Delegate, v8::Local GetGPUInfo(v8::Isolate* isolate, const std::string& info_type); void EnableSandbox(mate::Arguments* args); + void DisablePluginSandbox(const std::string& mime_type); void SetUserAgentFallback(const std::string& user_agent); std::string GetUserAgentFallback(); void SetBrowserClientCanUseCustomSiteInstance(bool should_disable); diff --git a/shell/browser/atom_browser_client.cc b/shell/browser/atom_browser_client.cc index 11dea7624dfac..c8a305e4b2d6b 100644 --- a/shell/browser/atom_browser_client.cc +++ b/shell/browser/atom_browser_client.cc @@ -36,6 +36,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" +#include "content/public/common/pepper_plugin_info.h" #include "content/public/common/service_names.mojom.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" @@ -1010,6 +1011,17 @@ bool AtomBrowserClient::PreSpawnRenderer(sandbox::TargetPolicy* policy) { } #endif // defined(OS_WIN) +bool AtomBrowserClient::IsPluginSandboxDisabled( + const content::PepperPluginInfo& info) { + const auto& unsandboxed_plugins = Browser::Get()->unsandboxed_plugins(); + for (const auto& item : info.mime_types) { + if (base::Contains(unsandboxed_plugins, item.mime_type)) { + return true; + } + } + return false; +} + std::string AtomBrowserClient::GetApplicationLocale() { if (BrowserThread::CurrentlyOn(BrowserThread::IO)) return g_io_thread_application_locale.Get(); diff --git a/shell/browser/atom_browser_client.h b/shell/browser/atom_browser_client.h index 26ca58d4efb2c..e864fd74031a3 100644 --- a/shell/browser/atom_browser_client.h +++ b/shell/browser/atom_browser_client.h @@ -180,6 +180,7 @@ class AtomBrowserClient : public content::ContentBrowserClient, #if defined(OS_WIN) bool PreSpawnRenderer(sandbox::TargetPolicy* policy) override; #endif + bool IsPluginSandboxDisabled(const content::PepperPluginInfo& info) override; // content::RenderProcessHostObserver: void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; diff --git a/shell/browser/browser.cc b/shell/browser/browser.cc index feee108a8eabf..2984aa2d701a7 100644 --- a/shell/browser/browser.cc +++ b/shell/browser/browser.cc @@ -175,6 +175,10 @@ const util::Promise& Browser::WhenReady(v8::Isolate* isolate) { return *ready_promise_; } +void Browser::DisablePluginSandbox(const std::string& mime_type) { + unsandboxed_plugins_.insert(mime_type); +} + void Browser::OnAccessibilitySupportChanged() { for (BrowserObserver& observer : observers_) observer.OnAccessibilitySupportChanged(); diff --git a/shell/browser/browser.h b/shell/browser/browser.h index e2379aedf5118..aba6af81d59d4 100644 --- a/shell/browser/browser.h +++ b/shell/browser/browser.h @@ -7,6 +7,7 @@ #include #include +#include #include #include "base/compiler_specific.h" @@ -266,6 +267,12 @@ class Browser : public WindowListObserver { bool is_ready() const { return is_ready_; } const util::Promise& WhenReady(v8::Isolate* isolate); + const std::unordered_set& unsandboxed_plugins() const { + return unsandboxed_plugins_; + } + + void DisablePluginSandbox(const std::string& mime_type); + protected: // Returns the version of application bundle or executable file. std::string GetExecutableFileVersion() const; @@ -311,6 +318,9 @@ class Browser : public WindowListObserver { base::DictionaryValue about_panel_options_; #endif + // Disable sandbox for these plugins by MIME type. + std::unordered_set unsandboxed_plugins_; + DISALLOW_COPY_AND_ASSIGN(Browser); };