Skip to content

Commit bc1cfad

Browse files
linesightclaude
andcommitted
Fix Linux subprocess crash: don't set no_sandbox=1 on Linux
cefApplicationSettings.no_sandbox=1 caused BasicStartupComplete() to append --no-sandbox to the browser command line early in startup. Chrome treats --no-sandbox as a signal to skip the Mojo IPC bootstrap fd registration (GlobalDescriptors key 7) for all child processes. Every subprocess (renderer, GPU, zygote) then crashed on startup with "Failed global descriptor lookup: 7", making CreateBrowserSync() hang indefinitely and causing all CI tests to time out. Fix: leave no_sandbox=0 on Linux so Chrome's startup code registers key 7 for every subprocess. Sandbox configuration is now handled entirely via command-line switches: --disable-setuid-sandbox (no chrome-sandbox binary shipped) --disable-namespace-sandbox (for environments lacking user namespaces) Unlike --no-sandbox, these two switches only skip the sandbox mechanism itself; they do not affect Mojo IPC fd setup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent fb56b04 commit bc1cfad

4 files changed

Lines changed: 50 additions & 9 deletions

File tree

examples/hello_world.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,29 @@
1717
def main():
1818
check_versions()
1919
sys.excepthook = cef.ExceptHook # To shutdown all CEF processes on error
20-
cef.Initialize()
20+
switches = {}
21+
if sys.platform.startswith("linux"):
22+
# cefpython does not ship a chrome-sandbox (setuid) binary.
23+
# Disable both the setuid and namespace sandboxes so Chrome runs
24+
# subprocesses without sandboxing. Unlike --no-sandbox, these two
25+
# flags do NOT suppress the Mojo IPC bootstrap fd registration
26+
# (GlobalDescriptors key 7), so subprocesses can still communicate.
27+
switches["disable-setuid-sandbox"] = ""
28+
switches["disable-namespace-sandbox"] = ""
29+
# /dev/shm may be too small in VMs and containers.
30+
switches["disable-dev-shm-usage"] = ""
31+
# Suppress the GNOME Keyring unlock prompt on desktop sessions.
32+
switches["password-store"] = "basic"
33+
# Virtual GPU hardware (e.g. VMware) may not expose the DMA-BUF / GBM
34+
# interface required by Chrome's GPU process. Keep the GPU in-process.
35+
switches["disable-gpu"] = ""
36+
switches["disable-gpu-compositing"] = ""
37+
switches["in-process-gpu"] = ""
38+
# Keep storage and network services in-process to reduce subprocess
39+
# spawning overhead.
40+
switches["disable-features"] = "StorageServiceOutOfProcess"
41+
switches["enable-features"] = "NetworkServiceInProcess"
42+
cef.Initialize(switches=switches)
2143
cef.CreateBrowserSync(url="https://www.google.com/",
2244
window_title="Hello World!")
2345
cef.MessageLoop()

src/cefpython.pyx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,8 +615,19 @@ def Initialize(applicationSettings=None, commandLineSwitches=None, **kwargs):
615615
g_applicationSettings[key] = copy.deepcopy(application_settings[key])
616616

617617
cdef CefSettings cefApplicationSettings
618-
# No sandboxing for the subprocesses
619-
cefApplicationSettings.no_sandbox = 1
618+
IF UNAME_SYSNAME == "Linux":
619+
# On Linux, leave no_sandbox=0 so Chrome's startup code registers the
620+
# Mojo IPC bootstrap fd (GlobalDescriptors key 7) for every subprocess.
621+
# Setting no_sandbox=1 would cause BasicStartupComplete() to append
622+
# --no-sandbox before fd registration, causing all subprocesses to crash
623+
# with "Failed global descriptor lookup: 7". Sandbox behaviour is instead
624+
# controlled via --disable-setuid-sandbox / --disable-namespace-sandbox
625+
# command-line switches passed by the caller.
626+
pass
627+
ELSE:
628+
# On Windows/macOS the sandbox helper binary is not shipped with
629+
# cefpython, so disable sandboxing entirely.
630+
cefApplicationSettings.no_sandbox = 1
620631
SetApplicationSettings(application_settings, &cefApplicationSettings)
621632

622633
# External message pump

unittests/main_test.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,13 @@ def test_main(self):
144144
# Chrome 130+ blocks window.open() called without a user gesture.
145145
switches = {"disable-popup-blocking": ""}
146146
if LINUX:
147-
# Disable the setuid sandbox helper (not shipped in our package)
148-
# so that Chrome falls back to the user-namespace sandbox, which
149-
# correctly passes the Mojo IPC bootstrap fd to subprocesses.
147+
# cefpython does not ship a chrome-sandbox (setuid) binary.
148+
# Disable both the setuid and namespace sandboxes so Chrome runs
149+
# subprocesses without sandboxing. Unlike --no-sandbox, these two
150+
# flags do NOT suppress the Mojo IPC bootstrap fd registration
151+
# (GlobalDescriptors key 7), so subprocesses can still communicate.
150152
switches["disable-setuid-sandbox"] = ""
153+
switches["disable-namespace-sandbox"] = ""
151154
# /dev/shm is too small in CI containers.
152155
switches["disable-dev-shm-usage"] = ""
153156
# GPU acceleration is not available under xvfb.
@@ -160,6 +163,8 @@ def test_main(self):
160163
# separate subprocess (reduces spawn overhead on CI).
161164
switches["disable-features"] = "StorageServiceOutOfProcess"
162165
switches["enable-features"] = "NetworkServiceInProcess"
166+
# Suppress the GNOME Keyring unlock prompt on desktop sessions.
167+
switches["password-store"] = "basic"
163168
cef.Initialize(settings, switches=switches)
164169
subtest_message("cef.Initialize() ok")
165170

unittests/osr_test.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,13 @@ def test_osr(self):
113113
"disable-surfaces": "", # This is required for PDF ext to work
114114
}
115115
if LINUX:
116-
# Disable the setuid sandbox helper (not shipped in our package)
117-
# so that Chrome falls back to the user-namespace sandbox, which
118-
# correctly passes the Mojo IPC bootstrap fd to subprocesses.
116+
# cefpython does not ship a chrome-sandbox (setuid) binary.
117+
# Disable both the setuid and namespace sandboxes so Chrome runs
118+
# subprocesses without sandboxing. Unlike --no-sandbox, these two
119+
# flags do NOT suppress the Mojo IPC bootstrap fd registration
120+
# (GlobalDescriptors key 7), so subprocesses can still communicate.
119121
switches["disable-setuid-sandbox"] = ""
122+
switches["disable-namespace-sandbox"] = ""
120123
# /dev/shm is too small in CI containers.
121124
switches["disable-dev-shm-usage"] = ""
122125
# Run GPU process inside the browser process so it is not

0 commit comments

Comments
 (0)