From 2f5f974a0ed66d10659d90d20128e71b3b44a097 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Tue, 28 Apr 2026 21:19:49 +0700 Subject: [PATCH] fix(desktop): match VS Code Linux sandbox handling, scope --no-sandbox to AppImage The Linux wrapper renamed the executable to Paseo.bin and exec'd it with --no-sandbox, which surfaced as Paseo.bin in the dock and process list on Ubuntu. Drop the wrapper and the chrome-sandbox deletion entirely. .deb/.rpm now ship chrome-sandbox SUID 4755 (electron-builder 26 default postinst, matches VS Code) and run Paseo directly with the Chromium sandbox on. AppImage cannot carry SUID, so --no-sandbox is now injected at runtime only when process.env.APPIMAGE is set. Fixes #602 Re #381 --- packages/desktop/scripts/after-pack.js | 32 -------------------------- packages/desktop/src/main.ts | 7 ++++++ 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/packages/desktop/scripts/after-pack.js b/packages/desktop/scripts/after-pack.js index 408aadae4..473689763 100644 --- a/packages/desktop/scripts/after-pack.js +++ b/packages/desktop/scripts/after-pack.js @@ -4,10 +4,6 @@ const path = require("path"); const { smokePackagedDesktopApp } = require("./smoke-packaged-desktop-app.js"); const EXECUTABLE_NAME = "Paseo"; -const WRAPPER_MODE = 0o755; -const WRAPPER_SCRIPT = `#!/bin/bash -exec "$(dirname "$(readlink -f "$0")")/${EXECUTABLE_NAME}.bin" --no-sandbox "$@" -`; // electron-builder arch enum → Node.js arch string const ARCH_MAP = { 0: "ia32", 1: "x64", 2: "armv7l", 3: "arm64", 4: "universal" }; @@ -131,39 +127,11 @@ exports.default = async function afterPack(context) { pruneNativeModules(context.appOutDir, platform, arch); - if (platform === "linux") { - prepareLinuxApp(context.appOutDir); - } - if (platform === "linux" || platform === "win32") { await smokeUnpackedAppIfRequested(context.appOutDir); } }; -function prepareLinuxApp(appOutDir) { - const chromeSandbox = path.join(appOutDir, "chrome-sandbox"); - if (fs.existsSync(chromeSandbox)) { - fs.unlinkSync(chromeSandbox); - console.log("Removed chrome-sandbox from Linux build"); - } - - const executablePath = path.join(appOutDir, EXECUTABLE_NAME); - const wrappedBinaryPath = path.join(appOutDir, `${EXECUTABLE_NAME}.bin`); - - if (!fs.existsSync(wrappedBinaryPath)) { - if (!fs.existsSync(executablePath)) { - throw new Error(`Expected Linux executable at ${executablePath}`); - } - - fs.renameSync(executablePath, wrappedBinaryPath); - console.log(`Renamed ${EXECUTABLE_NAME} to ${EXECUTABLE_NAME}.bin for Linux wrapper`); - } - - fs.writeFileSync(executablePath, WRAPPER_SCRIPT, { mode: WRAPPER_MODE }); - fs.chmodSync(executablePath, WRAPPER_MODE); - console.log(`Created Linux wrapper for ${EXECUTABLE_NAME} with --no-sandbox`); -} - async function smokeUnpackedAppIfRequested(appOutDir) { if (process.env.PASEO_DESKTOP_SMOKE !== "1") { return; diff --git a/packages/desktop/src/main.ts b/packages/desktop/src/main.ts index 8b641829c..0085b45b5 100644 --- a/packages/desktop/src/main.ts +++ b/packages/desktop/src/main.ts @@ -86,6 +86,13 @@ if (forcedUserDataDir) { } } +// AppImage runtimes mount the app from /tmp under the user's UID, so the SUID +// chrome-sandbox helper we ship in .deb/.rpm cannot work there. Disable the +// sandbox only in that case; .deb/.rpm keep the sandbox on, matching VS Code. +if (process.platform === "linux" && process.env.APPIMAGE) { + app.commandLine.appendSwitch("no-sandbox"); +} + // Allow users to pass Chromium flags via PASEO_ELECTRON_FLAGS for debugging // rendering issues (e.g. "--disable-gpu --ozone-platform=x11"). // Must run before app.whenReady().