Skip to content

fix(desktop): configure Linux Electron sandbox helper - #37529

Closed
Jgracier wants to merge 1 commit into
NousResearch:mainfrom
Jgracier:fix/linux-desktop-chrome-sandbox
Closed

fix(desktop): configure Linux Electron sandbox helper#37529
Jgracier wants to merge 1 commit into
NousResearch:mainfrom
Jgracier:fix/linux-desktop-chrome-sandbox

Conversation

@Jgracier

@Jgracier Jgracier commented Jun 2, 2026

Copy link
Copy Markdown

Why

hermes desktop builds an unpacked Electron app on Linux, but Electron's generated chrome-sandbox helper is user-owned with mode 755. Chromium aborts before the desktop app starts unless that helper is owned by root with mode 4755.

The existing install.sh --include-desktop path was also macOS-only after the build step: it searched only for Hermes.app, so a successful Linux build was reported as missing.

What changed

  • Configure the Linux Electron sandbox helper as root:root 4755 before launching a locally built desktop app.
  • Recognize the Linux unpacked desktop artifact in install.sh --include-desktop and configure its sandbox helper after build.
  • Add regression coverage for the Linux launcher repair path.

Verification

  • bash -n scripts/install.sh
  • python -m pytest tests/hermes_cli/test_gui_command.py -q
  • python -m pytest tests/test_install_sh_setup_wizard_tty_probe.py tests/test_install_sh_root_fhs_uv_python_path.py tests/test_install_sh_symlink_stomp.py -q
  • Simulated a post-build user-owned 755 helper and confirmed hermes desktop --skip-build repairs it and launches the sandboxed Electron process.

@Jgracier
Jgracier marked this pull request as ready for review June 2, 2026 17:36
@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have labels Jun 2, 2026
@austinpickett
austinpickett requested a review from Copilot June 2, 2026 21:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Linux-specific issues when launching a locally built Electron desktop app by ensuring Electron’s chrome-sandbox helper is configured with the required root:root ownership and 4755 mode, and by updating the installer to recognize Linux unpacked desktop artifacts.

Changes:

  • Add a Linux sandbox helper repair step to hermes desktop/gui before launching the packaged app.
  • Update scripts/install.sh --include-desktop to detect Linux unpacked artifacts (not only macOS .app) and configure chrome-sandbox.
  • Add a regression test covering the Linux launcher sandbox repair path.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tests/hermes_cli/test_gui_command.py Adds regression coverage asserting sudo chown/sudo chmod are invoked before launching on Linux.
scripts/install.sh Detects Linux unpacked desktop output and attempts to configure chrome-sandbox after build.
hermes_cli/main.py Implements Linux chrome-sandbox fixup in the packaged-app launch path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hermes_cli/main.py
Comment on lines +6938 to +6945
sandbox = packaged_executable.parent / "chrome-sandbox"
if not sandbox.exists():
print(f"✗ Hermes Desktop is missing Electron's Linux sandbox helper: {sandbox}")
return False

sandbox_stat = sandbox.stat()
if sandbox_stat.st_uid == 0 and stat.S_IMODE(sandbox_stat.st_mode) == 0o4755:
return True
Comment thread scripts/install.sh
Comment on lines +2421 to +2431
if [ "$OS" = "linux" ]; then
local sandbox="$desktop_dir/release/linux-unpacked/chrome-sandbox"
if [ "$(id -u)" -eq 0 ]; then
chown root:root "$sandbox" && chmod 4755 "$sandbox"
elif command -v sudo >/dev/null 2>&1; then
sudo chown root:root "$sandbox" && sudo chmod 4755 "$sandbox"
else
log_error "Cannot configure Electron sandbox helper without sudo: $sandbox"
return 1
fi
fi
ethernet8023 added a commit that referenced this pull request Jun 3, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes #37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
@teknium1

teknium1 commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Flagging a design concern on the launch-path fixup before this lands (Ari is picking this up).

The core issue: the launcher must not depend on sudo being obtainable.

_desktop_linux_sandbox_fixup() spawns sudo chown/chmod during a plain hermes desktop launch. That fails hard for a large class of users:

  • locked-down / managed machines where the user has no sudo
  • non-admin accounts
  • containers / CI without sudo

We can't assume root is reachable, so auto-sudo can't be the default launch behavior.

The clean alternative (zero-root) is not reliably available either.

Modern Electron sandboxes via unprivileged user namespaces with no SUID helper at all — but you can't detect availability from sysctls; the knobs lie. Probed on a stock Ubuntu 24.04 box:

kernel.unprivileged_userns_clone = 1          # says "allowed"
user.max_user_namespaces = 255646             # plenty
kernel.apparmor_restrict_unprivileged_userns = 1   # but AppArmor restricts
# actual runtime test:
unshare --user --map-root-user echo ok
  -> write failed /proc/self/uid_map: Operation not permitted   # BLOCKED

So userns is blocked out of the box on current Ubuntu defaults, and the only way to know is a runtime unshare probe, not reading sysctls.

Suggested launch logic (never spawns sudo itself):

  1. Runtime-probe whether an unprivileged userns can be created (try unshare, not sysctl).
  2. userns works -> launch normally, full sandbox, no root. Done.
  3. userns blocked but chrome-sandbox is already root:root 4755 -> launch, full sandbox.
  4. userns blocked AND helper not setuid -> we cannot get a sandbox without root. Do NOT silently --no-sandbox. Print the exact chown/chmod commands for users who do have sudo, and let them opt into --no-sandbox with a clear "reduced isolation" warning.

Principle: the launcher detects and informs; it never assumes root is obtainable and never escalates on the user's behalf.

The install.sh --include-desktop changes are fine to keep — the installer path may legitimately have root and the escalation there is explicit. It's specifically the auto-sudo in the launch path that should become the probe-and-inform flow above.

Context: reported on Discord — Linux users currently have to run the manual chown/chmod dance, which is what motivated this PR. The fix is right to pursue; it just shouldn't require sudo at launch.

Yuki-14544869 pushed a commit to Yuki-14544869/hermes-agent that referenced this pull request Jun 4, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
davidgut1982 pushed a commit to davidgut1982/hermes-agent that referenced this pull request Jun 5, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
changman pushed a commit to changman/hermes-agent that referenced this pull request Jun 10, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
alt-glitch pushed a commit that referenced this pull request Jun 14, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes #37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
kossteg pushed a commit to kossteg/hermes-agent that referenced this pull request Jun 16, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
T02200059 pushed a commit to T02200059/hermes-agent that referenced this pull request Jun 18, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
donbowman pushed a commit to donbowman/hermes-agent that referenced this pull request Jul 13, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
Electron's chrome-sandbox helper must be root:root 4755 on Linux or the
sandboxed renderer aborts before the desktop app starts. The existing
installer only searched for macOS .app bundles, so a successful Linux
build was reported as missing.

Changes:
- Add _desktop_linux_sandbox_fixup() to hermes_cli/main.py, called
  before launching a packaged desktop app on Linux.
- Use lstat() + S_ISREG check to reject symlinks — chown/chmod on a
  symlink target would set SUID on an arbitrary path.
- Update install.sh to recognize Linux unpacked artifacts and configure
  chrome-sandbox with proper error handling (the original PR silently
  ignored chown/chmod failures).
- Add regression tests: normal fixup flow, symlink rejection, and
  already-configured skip path.

Closes NousResearch#37529 (rebased, merge conflicts resolved, copilot review
feedback addressed).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants