Browse Source

Fix process.execPath returning parent process path instead of the helper in sandboxed renderer (#13839)

Milan Burda 6 years ago
parent
commit
db38c8b620

+ 10 - 1
atom/renderer/atom_sandboxed_renderer_client.cc

@@ -12,8 +12,10 @@
 #include "atom/common/options_switches.h"
 #include "atom/renderer/api/atom_api_renderer_ipc.h"
 #include "atom/renderer/atom_render_frame_observer.h"
+#include "base/base_paths.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
+#include "base/path_service.h"
 #include "chrome/renderer/printing/print_web_view_helper.h"
 #include "content/public/renderer/render_frame.h"
 #include "native_mate/dictionary.h"
@@ -81,6 +83,12 @@ base::CommandLine::StringVector GetArgv() {
   return base::CommandLine::ForCurrentProcess()->argv();
 }
 
+base::FilePath::StringType GetExecPath() {
+  base::FilePath path;
+  PathService::Get(base::FILE_EXE, &path);
+  return path.value();
+}
+
 v8::Local<v8::Value> CreatePreloadScript(v8::Isolate* isolate,
                                          v8::Local<v8::String> preloadSrc) {
   auto script = v8::Script::Compile(preloadSrc);
@@ -97,6 +105,7 @@ void InitializeBindings(v8::Local<v8::Object> binding,
   b.SetMethod("crash", AtomBindings::Crash);
   b.SetMethod("hang", AtomBindings::Hang);
   b.SetMethod("getArgv", GetArgv);
+  b.SetMethod("getExecPath", GetExecPath);
   b.SetMethod("getHeapStatistics", &AtomBindings::GetHeapStatistics);
   b.SetMethod("getProcessMemoryInfo", &AtomBindings::GetProcessMemoryInfo);
   b.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo);
@@ -105,7 +114,7 @@ void InitializeBindings(v8::Local<v8::Object> binding,
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kGuestInstanceID))
     b.Set(options::kGuestInstanceID,
-        command_line->GetSwitchValueASCII(switches::kGuestInstanceID));
+          command_line->GetSwitchValueASCII(switches::kGuestInstanceID));
 }
 
 class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver {

+ 13 - 0
docs/api/process.md

@@ -8,6 +8,19 @@ Electron's `process` object is extended from the
 [Node.js `process` object](https://nodejs.org/api/process.html).
 It adds the following events, properties, and methods:
 
+## Sandbox
+
+In sandboxed renderers the `process` object contains only a subset of the APIs:
+- `crash()`
+- `hang()`
+- `getHeapStatistics()`
+- `getProcessMemoryInfo()`
+- `getSystemMemoryInfo()`
+- `argv`
+- `execPath`
+- `env`
+- `platform`
+
 ## Events
 
 ### Event: 'loaded'

+ 0 - 1
lib/browser/rpc-server.js

@@ -454,7 +454,6 @@ ipcMain.on('ELECTRON_BROWSER_SANDBOX_LOAD', function (event, preloadPath) {
     preloadSrc: preloadSrc,
     preloadError: preloadError,
     platform: process.platform,
-    execPath: process.execPath,
     env: process.env
   }
 })

+ 3 - 3
lib/sandboxed_renderer/init.js

@@ -36,7 +36,7 @@ const loadedModules = new Map([
 ])
 
 const {
-  preloadSrc, preloadError, platform, execPath, env
+  preloadSrc, preloadError, platform, env
 } = electron.ipcRenderer.sendSync('ELECTRON_BROWSER_SANDBOX_LOAD', preloadPath)
 
 require('../renderer/web-frame-init')()
@@ -49,9 +49,9 @@ preloadProcess.hang = () => binding.hang()
 preloadProcess.getHeapStatistics = () => binding.getHeapStatistics()
 preloadProcess.getProcessMemoryInfo = () => binding.getProcessMemoryInfo()
 preloadProcess.getSystemMemoryInfo = () => binding.getSystemMemoryInfo()
-preloadProcess.argv = binding.getArgv()
+preloadProcess.argv = process.argv = binding.getArgv()
+preloadProcess.execPath = process.execPath = binding.getExecPath()
 preloadProcess.platform = process.platform = platform
-preloadProcess.execPath = process.execPath = execPath
 preloadProcess.env = process.env = env
 
 process.on('exit', () => preloadProcess.emit('exit'))

+ 4 - 2
spec/api-browser-window-spec.js

@@ -1600,9 +1600,11 @@ describe('BrowserWindow module', () => {
         })
       })
 
-      it('validate process.env access in sandbox renderer', (done) => {
+      it('validates process APIs access in sandboxed renderer', (done) => {
         ipcMain.once('answer', function (event, test) {
-          assert.equal(test, 'foo')
+          assert.equal(test.platform, remote.process.platform)
+          assert.deepEqual(test.env, remote.process.env)
+          assert.equal(test.execPath, remote.process.helperExecPath)
           done()
         })
         remote.process.env.sandboxmain = 'foo'

+ 5 - 1
spec/fixtures/module/preload-sandbox.js

@@ -8,7 +8,11 @@
     window.test = 'preload'
     window.process = process
     if (process.env.sandboxmain) {
-      window.test = process.env.sandboxmain
+      window.test = {
+        env: process.env,
+        execPath: process.execPath,
+        platform: process.platform
+      }
     }
   } else if (location.href !== 'about:blank') {
     addEventListener('DOMContentLoaded', () => {