fix: AppImage required --no-sandbox
Queue Release Build / prepare (push) Successful in 28s
Deploy Web Apps / deploy (push) Failing after 10m14s
Queue Release Build / build-windows (push) Failing after 15m12s
Queue Release Build / build-linux (push) Successful in 43m41s
Queue Release Build / finalize (push) Skipped
Queue Release Build / build-android (push) Successful in 17m25s
Queue Release Build / prepare (push) Successful in 28s
Deploy Web Apps / deploy (push) Failing after 10m14s
Queue Release Build / build-windows (push) Failing after 15m12s
Queue Release Build / build-linux (push) Successful in 43m41s
Queue Release Build / finalize (push) Skipped
Queue Release Build / build-android (push) Successful in 17m25s
Not tested enough but works on my machine
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
export const LINUX_LAUNCHER_BINARY_SUFFIX = '-bin';
|
||||
|
||||
export const APPARMOR_USERNS_RESTRICTION_PATH = '/proc/sys/kernel/apparmor_restrict_unprivileged_userns';
|
||||
export const UNPRIVILEGED_USERNS_CLONE_PATH = '/proc/sys/kernel/unprivileged_userns_clone';
|
||||
export const MAX_USER_NAMESPACES_PATH = '/proc/sys/user/max_user_namespaces';
|
||||
|
||||
export interface LinuxLauncherNames {
|
||||
launcherFileName: string;
|
||||
binaryFileName: string;
|
||||
}
|
||||
|
||||
export interface LinuxLauncherScriptOptions {
|
||||
binaryFileName: string;
|
||||
apparmorRestrictionPath?: string;
|
||||
unprivilegedUsernsClonePath?: string;
|
||||
maxUserNamespacesPath?: string;
|
||||
}
|
||||
|
||||
export function resolveLinuxLauncherNames(executableName: string): LinuxLauncherNames {
|
||||
return {
|
||||
launcherFileName: executableName,
|
||||
binaryFileName: `${executableName}${LINUX_LAUNCHER_BINARY_SUFFIX}`
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Chromium reads `--no-sandbox` while the browser process boots, long before
|
||||
* the main script runs, so `app.commandLine.appendSwitch` cannot influence it.
|
||||
* The packaged executable is therefore this script, which decides before
|
||||
* handing over to the real binary.
|
||||
*
|
||||
* The sandbox stays on wherever the kernel can host it. It is dropped only
|
||||
* where unprivileged user namespaces are denied - Ubuntu 24.04+ confines
|
||||
* unconfined binaries through AppArmor, and hardened kernels disable the
|
||||
* namespaces outright. An AppImage cannot fall back to the SUID helper because
|
||||
* its payload is mounted `nosuid`, so without this the app aborts at startup.
|
||||
*/
|
||||
export function buildLinuxLauncherScript(options: LinuxLauncherScriptOptions): string {
|
||||
const apparmorRestrictionPath = options.apparmorRestrictionPath ?? APPARMOR_USERNS_RESTRICTION_PATH;
|
||||
const unprivilegedUsernsClonePath = options.unprivilegedUsernsClonePath ?? UNPRIVILEGED_USERNS_CLONE_PATH;
|
||||
const maxUserNamespacesPath = options.maxUserNamespacesPath ?? MAX_USER_NAMESPACES_PATH;
|
||||
|
||||
return [
|
||||
'#!/bin/sh',
|
||||
'# Generated during packaging. Chromium only honours --no-sandbox when it is',
|
||||
'# present on the real command line, so the decision happens here.',
|
||||
'set -eu',
|
||||
'',
|
||||
'launcher_path="$0"',
|
||||
'',
|
||||
'case "$launcher_path" in',
|
||||
' */*) ;;',
|
||||
' *) launcher_path="$(command -v -- "$launcher_path" 2>/dev/null || printf \'%s\' "$launcher_path")" ;;',
|
||||
'esac',
|
||||
'',
|
||||
'launcher_path="$(readlink -f -- "$launcher_path" 2>/dev/null || printf \'%s\' "$launcher_path")"',
|
||||
`binary_path="$(dirname -- "$launcher_path")/${options.binaryFileName}"`,
|
||||
'',
|
||||
'read_kernel_flag() {',
|
||||
' if [ ! -r "$1" ]; then',
|
||||
' printf \'%s\' "$2"',
|
||||
' return 0',
|
||||
' fi',
|
||||
'',
|
||||
' cat -- "$1" 2>/dev/null || printf \'%s\' "$2"',
|
||||
'}',
|
||||
'',
|
||||
'sandbox_is_blocked() {',
|
||||
` if [ "$(read_kernel_flag ${apparmorRestrictionPath} 0)" = "1" ]; then`,
|
||||
' return 0',
|
||||
' fi',
|
||||
'',
|
||||
` if [ "$(read_kernel_flag ${unprivilegedUsernsClonePath} 1)" = "0" ]; then`,
|
||||
' return 0',
|
||||
' fi',
|
||||
'',
|
||||
` if [ "$(read_kernel_flag ${maxUserNamespacesPath} 1)" = "0" ]; then`,
|
||||
' return 0',
|
||||
' fi',
|
||||
'',
|
||||
' return 1',
|
||||
'}',
|
||||
'',
|
||||
'for launcher_arg in "$@"; do',
|
||||
' case "$launcher_arg" in',
|
||||
' --no-sandbox) exec "$binary_path" "$@" ;;',
|
||||
' esac',
|
||||
'done',
|
||||
'',
|
||||
'if sandbox_is_blocked; then',
|
||||
' exec "$binary_path" --no-sandbox "$@"',
|
||||
'fi',
|
||||
'',
|
||||
'exec "$binary_path" "$@"',
|
||||
''
|
||||
].join('\n');
|
||||
}
|
||||
Reference in New Issue
Block a user