From 6f6bd35b964c8a7870ac75d2bcd0abee4ff0df12 Mon Sep 17 00:00:00 2001 From: The412Banner <205237651+The412Banner@users.noreply.github.com> Date: Mon, 5 Oct 2026 13:37:08 -0400 Subject: [PATCH] Firefox: skip shared-memory seals (tabs crash on Android 16) (#280) On Android 16 phones (Galaxy S25 SM-S931B, SM-S948B, RedMagic NP05J) every Firefox and LibreWolf tab dies at once: Firefox seals the size of the shared memory it hands a tab, adding the seal fails there, Firefox only warns, and the tab refuses the unsealed memory ("IPDL protocol error: Shared memory PlatformHandle is not safe to map") and exits on signal 11. The window opens; no page ever loads. MOZ_SHM_NO_SEALS=1 is Firefox's own switch to skip the seals (ipc/glue/SharedMemoryPlatform_posix.cpp). Set it beside the sandbox switches in all three places a browser starts from: the desktop session, AppImages, and Flatpak sandboxes. Co-authored-by: The412Banner --- .../main/java/com/droiddeck/launcher/runtime/BwrapSpawner.kt | 5 ++++- tools/linuxfs/desktop/droiddeck-desktop | 5 +++++ tools/linuxfs/overlay/usr/local/bin/droiddeck-appimage-run | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/droiddeck/launcher/runtime/BwrapSpawner.kt b/app/src/main/java/com/droiddeck/launcher/runtime/BwrapSpawner.kt index 6e20ff89d..3d7000228 100644 --- a/app/src/main/java/com/droiddeck/launcher/runtime/BwrapSpawner.kt +++ b/app/src/main/java/com/droiddeck/launcher/runtime/BwrapSpawner.kt @@ -300,7 +300,10 @@ object BwrapSpawner { // session has Xwayland) it stays on X11, which works. GTK and Qt go by their own settings. if (env.containsKey("DISPLAY")) env["XDG_SESSION_TYPE"] = "x11" for (name in listOf("MOZ_DISABLE_CONTENT_SANDBOX", "MOZ_DISABLE_GMP_SANDBOX", "MOZ_DISABLE_RDD_SANDBOX", - "MOZ_DISABLE_SOCKET_PROCESS_SANDBOX", "MOZ_DISABLE_UTILITY_SANDBOX")) { + "MOZ_DISABLE_SOCKET_PROCESS_SANDBOX", "MOZ_DISABLE_UTILITY_SANDBOX", + // Android 16 refuses the size seal Firefox puts on a tab's shared + // memory, and the tab then dies on every page (droiddeck-desktop). + "MOZ_SHM_NO_SEALS")) { env.putIfAbsent(name, "1") } } diff --git a/tools/linuxfs/desktop/droiddeck-desktop b/tools/linuxfs/desktop/droiddeck-desktop index 7c7883b6a..b69c2a993 100644 --- a/tools/linuxfs/desktop/droiddeck-desktop +++ b/tools/linuxfs/desktop/droiddeck-desktop @@ -16,6 +16,11 @@ export QT_QPA_PLATFORMTHEME=lxqt # The prefs for this are only advisory and a profile can override them; the environment is not. export MOZ_DISABLE_CONTENT_SANDBOX=1 MOZ_DISABLE_GMP_SANDBOX=1 MOZ_DISABLE_RDD_SANDBOX=1 export MOZ_DISABLE_SOCKET_PROCESS_SANDBOX=1 MOZ_DISABLE_UTILITY_SANDBOX=1 +# Firefox seals the size of the shared memory it hands a tab; on Android 16 (Galaxy S25/S26, +# RedMagic) adding the seal fails, Firefox only warns, and the tab refuses the unsealed memory +# ("Shared memory PlatformHandle is not safe to map") and dies on signal 11 - every page. Firefox's +# own switch skips the seals. +export MOZ_SHM_NO_SEALS=1 # pixman composites in software and gives programs shm buffers only, so a Vulkan program on it # fails at its swapchain. vulkan (or gles2) composite on the GPU and give programs DMA-BUFs, but # stock wlroots allocates through gbm on a real DRM node and the KGSL stand-in is not one ("unable diff --git a/tools/linuxfs/overlay/usr/local/bin/droiddeck-appimage-run b/tools/linuxfs/overlay/usr/local/bin/droiddeck-appimage-run index 946a64601..847c272b6 100755 --- a/tools/linuxfs/overlay/usr/local/bin/droiddeck-appimage-run +++ b/tools/linuxfs/overlay/usr/local/bin/droiddeck-appimage-run @@ -24,6 +24,8 @@ fi # X11, which it picks from the session type. export MOZ_DISABLE_CONTENT_SANDBOX=1 MOZ_DISABLE_GMP_SANDBOX=1 MOZ_DISABLE_RDD_SANDBOX=1 export MOZ_DISABLE_SOCKET_PROCESS_SANDBOX=1 MOZ_DISABLE_UTILITY_SANDBOX=1 +# Android 16 refuses Firefox the size seal on a tab's shared memory; see droiddeck-desktop. +export MOZ_SHM_NO_SEALS=1 # sharun images start the app through their own ld.so, patched not to read /etc/ld.so.preload, and # drop LD_PRELOAD unless allowed: without this the app never gets the session's pads. if [ -s /etc/ld.so.preload ]; then