Launch native Hermes without privileged sandbox setup

Use the same direct executable path for menu launches and URLs, require working user namespaces, and retain only the first-update relaunch gate backport. This avoids the upstream CLI fallback that makes a helper in the user runtime setuid-root.

Co-Authored-By: GPT-6 Codex (xhigh) <noreply@openai.com>
This commit is contained in:
Spencer BullandGPT-6 Codex committed 2026-09-07 03:17:42 -05:00
1 parent 9588b28cf6
commit 2fb9ab2ba9
4 files changed
+71 -130

No files matched your search

-68
View File
@@ -1,71 +1,3 @@
--- a/hermes_cli/main.py
+++ b/hermes_cli/main.py
@@ -8146,6 +8146,44 @@
return False
+def _desktop_linux_userns_sandbox_available() -> bool:
+ """True when the unprivileged userns sandbox works (probed with ``unshare``, fails closed) — then
+ the setuid ``chrome-sandbox`` helper is never consulted and no sudo prompt is needed."""
+ if sys.platform != "linux":
+ return False
+ unshare = shutil.which("unshare")
+ if not unshare:
+ return False
+ try:
+ return (
+ subprocess.run(
+ [unshare, "--user", "--map-root-user", "true"],
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=5, check=False,
+ ).returncode
+ == 0)
+ except (OSError, subprocess.TimeoutExpired):
+ return False
+
+def _sandbox_helper_lstat(packaged_executable: Path) -> tuple[Path, Optional[os.stat_result]]:
+ """``(chrome-sandbox path, lstat or None)`` — lstat so a symlink is inspected, not followed."""
+ sandbox = packaged_executable.parent / "chrome-sandbox"
+ try:
+ return sandbox, sandbox.lstat()
+ except OSError:
+ return sandbox, None
+
+def _sandbox_helper_is_setuid_root(st: os.stat_result) -> bool:
+ return st.st_uid == 0 and stat.S_IMODE(st.st_mode) == 0o4755
+
+def _desktop_linux_needs_disable_setuid_sandbox(packaged_executable: Path) -> bool:
+ """True when a present, non-setuid ``chrome-sandbox`` would make Chromium abort with
+ ``setuid_sandbox_host`` despite a working userns sandbox (call after the fixup's userns path)."""
+ if sys.platform != "linux":
+ return False
+ _sandbox, st = _sandbox_helper_lstat(packaged_executable)
+ return st is not None and stat.S_ISREG(st.st_mode) and not _sandbox_helper_is_setuid_root(st)
+
+
def _desktop_linux_sandbox_helper_is_regular_file(packaged_executable: Path) -> bool:
"""Return True when ``chrome-sandbox`` exists as a regular file."""
if sys.platform != "linux":
@@ -8182,6 +8220,10 @@
return False
if sandbox_lstat.st_uid == 0 and stat.S_IMODE(sandbox_lstat.st_mode) == 0o4755:
+ return True
+
+ if _desktop_linux_userns_sandbox_available():
+ print("✓ Using Chromium's user-namespace sandbox (setuid helper not needed).")
return True
sudo = shutil.which("sudo")
@@ -8591,6 +8633,9 @@
launch_command.append("--no-sandbox")
else:
sys.exit(1)
+
+ elif _desktop_linux_needs_disable_setuid_sandbox(packaged_executable):
+ launch_command.append("--disable-setuid-sandbox")
launch_command.extend(config_electron_flags)
print(f"→ Launching packaged Hermes Desktop: {' '.join(launch_command)}")
--- a/scripts/desktop-update/posix.sh
+++ b/scripts/desktop-update/posix.sh
@@ -317,6 +317,8 @@