From 74c1b946e00c89b3b7ff315033d579ccb653de2d Mon Sep 17 00:00:00 2001 From: ygd58 Date: Mon, 4 May 2026 05:26:57 -0700 Subject: [PATCH] fix(browser): inject --no-sandbox for root and AppArmor userns restrictions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On VPS/Docker and some Ubuntu 23.10+ hosts, Chromium refuses to start without --no-sandbox: - uid=0 (root): hard requirement (VPS/Docker deployments) - AppArmor apparmor_restrict_unprivileged_userns=1 (Ubuntu 23.10+): non-root too, under systemd or unprivileged containers Detect both conditions and inject AGENT_BROWSER_CHROME_FLAGS with --no-sandbox --disable-dev-shm-usage when the user hasn't already set the flags themselves. Salvage of #15771 — only the browser_tool.py fix is cherry-picked. The PR's accompanying MCP preset addition (new feature surface) was dropped so the bug fix can land independently. Co-authored-by: ygd58 --- tools/browser_tool.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tools/browser_tool.py b/tools/browser_tool.py index 768cec7f71..f394e5b2f6 100644 --- a/tools/browser_tool.py +++ b/tools/browser_tool.py @@ -1482,6 +1482,34 @@ def _run_browser_command( if "AGENT_BROWSER_IDLE_TIMEOUT_MS" not in browser_env: idle_ms = str(BROWSER_SESSION_INACTIVITY_TIMEOUT * 1000) browser_env["AGENT_BROWSER_IDLE_TIMEOUT_MS"] = idle_ms + + # Inject --no-sandbox when needed (issue #15765): + # - Running as root: Chromium always refuses to start without it + # - Ubuntu 23.10+ / AppArmor systems: unprivileged user namespaces + # are restricted, causing Chromium to exit with "No usable sandbox" + # even for non-root users running under systemd or containers. + if "AGENT_BROWSER_CHROME_FLAGS" not in browser_env: + _needs_sandbox_bypass = False + if hasattr(os, "geteuid") and os.geteuid() == 0: + _needs_sandbox_bypass = True + logger.debug("browser: running as root — injecting --no-sandbox") + else: + # Detect AppArmor user namespace restrictions (Ubuntu 23.10+) + _userns_restrict = "/proc/sys/kernel/apparmor_restrict_unprivileged_userns" + try: + with open(_userns_restrict) as _f: + if _f.read().strip() == "1": + _needs_sandbox_bypass = True + logger.debug( + "browser: AppArmor userns restrictions detected — " + "injecting --no-sandbox" + ) + except OSError: + pass + if _needs_sandbox_bypass: + browser_env["AGENT_BROWSER_CHROME_FLAGS"] = ( + "--no-sandbox --disable-dev-shm-usage" + ) # Use temp files for stdout/stderr instead of pipes. # agent-browser starts a background daemon that inherits file