Browse Source

fix: allow unsandboxed renderers to request new privileges (#19953)

* fix: allow unsandboxed renderers to request new privileges

* add test
Jeremy Apthorp 5 years ago
parent
commit
832c926712

+ 1 - 0
patches/chromium/.patches

@@ -75,3 +75,4 @@ disable_color_correct_rendering.patch
 add_contentgpuclient_precreatemessageloop_callback.patch
 picture-in-picture.patch
 disable_compositor_recycling.patch
+allow_new_privileges_in_unsandboxed_child_processes.patch

+ 30 - 0
patches/chromium/allow_new_privileges_in_unsandboxed_child_processes.patch

@@ -0,0 +1,30 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jeremy Apthorp <[email protected]>
+Date: Mon, 26 Aug 2019 12:02:51 -0700
+Subject: allow new privileges in unsandboxed child processes
+
+This allows unsandboxed renderers to launch setuid processes on Linux.
+
+diff --git a/content/browser/child_process_launcher_helper_linux.cc b/content/browser/child_process_launcher_helper_linux.cc
+index 720b92a1a3a7ab5512f839005b272e4989d2ac65..b1759109627cd00053489dcdd397e942fa9d289f 100644
+--- a/content/browser/child_process_launcher_helper_linux.cc
++++ b/content/browser/child_process_launcher_helper_linux.cc
+@@ -54,6 +54,18 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
+     const int sandbox_fd = SandboxHostLinux::GetInstance()->GetChildSocket();
+     options->fds_to_remap.push_back(
+         std::make_pair(sandbox_fd, service_manager::GetSandboxFD()));
++
++    // (For Electron), if we're launching without zygote, that means we're
++    // launching an unsandboxed process (since all sandboxed processes are
++    // forked from the zygote). Relax the allow_new_privs option to permit
++    // launching suid processes from unsandboxed renderers.
++    service_manager::ZygoteHandle zygote_handle =
++        base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoZygote)
++            ? nullptr
++            : delegate_->GetZygote();
++    if (!zygote_handle) {
++      options->allow_new_privs = true;
++    }
+   }
+ 
+   options->environment = delegate_->GetEnvironment();

+ 13 - 0
spec/node-spec.js

@@ -155,6 +155,19 @@ describe('node feature', () => {
         })
       })
     })
+
+    describe('child_process.exec', () => {
+      (process.platform === 'linux' ? it : it.skip)('allows executing a setuid binary from non-sandboxed renderer', () => {
+        // Chrome uses prctl(2) to set the NO_NEW_PRIVILEGES flag on Linux (see
+        // https://github.com/torvalds/linux/blob/40fde647cc/Documentation/userspace-api/no_new_privs.rst).
+        // We disable this for unsandboxed processes, which the remote tests
+        // are running in. If this test fails with an error like 'effective uid
+        // is not 0', then it's likely that our patch to prevent the flag from
+        // being set has become ineffective.
+        const stdout = ChildProcess.execSync('sudo --help')
+        expect(stdout).to.not.be.empty()
+      })
+    })
   })
 
   describe('contexts', () => {