The actual bug

WPS Office’s flatpak ships a background helper called wpscloudsvr that reliably segfaults … null-pointer deref inside libqingbangong.so, r15=0x0, the works. Not a config issue, not something I broke, just a genuinely broken binary shipped in the package. It doesn’t crash the whole app, just spams crash reports and burns CPU respawning itself.

The fix nobody’s going to like, but it works

You can’t easily patch a binary inside a flatpak sandbox, and there’s no config flag to just disable this one helper. So: bind-mount /dev/null directly over the broken executable. The file still “exists” as far as the OS is concerned, it just contains nothing … attempting to execute it does nothing, silently, forever.

mount --bind /dev/null "$CURRENT_TARGET"

Crude. Also completely effective, and unlike trying to chmod -x it or delete it, this survives the app trying to repair itself, because the flatpak runtime still sees a file sitting exactly where it expects one.

The part that actually took the effort: making it stick

A one-off bind mount doesn’t survive a reboot, and flatpak updates regularly move the actual binary to a new content-hash directory, which would silently un-mask it the moment WPS updates. Neither of those is acceptable for something you want to just stay fixed.

Resolving the path dynamically instead of hardcoding it:

APP_ID="com.wps.Office"
TARGET_REL="extra/wps-office/office6/wpscloudsvr"

DEPLOY_DIR=$(flatpak info --show-location "$APP_ID")
CURRENT_TARGET="$DEPLOY_DIR/files/$TARGET_REL"

flatpak info --show-location always returns wherever the current deployment actually lives, regardless of which content-hash directory that happens to be today. That’s the whole trick … never hardcode the hash, always ask flatpak where it currently thinks the app is.

Idempotent (big word! Lol), so it’s safe to call repeatedly without erroring:

if mountpoint -q "$CURRENT_TARGET"; then
  echo "Already masked at: $CURRENT_TARGET"
  exit 0
fi

Two systemd units cover the two ways this needs to reapply itself … once at boot (since bind mounts don’t survive a restart), and once live, any time flatpak actually updates the app and moves the binary to a new hash path:

# wps-cloudsvr-mask-boot.service
[Unit]
Description=LinuxTweaks Mask wpscloudsvr on boot
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/mask-wps-cloudsvr.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
# wps-cloudsvr-mask.path
[Unit]
Description=LinuxTweaks Watch for WPS flatpak updates and re-mask

[Path]
PathModified=/var/lib/flatpak/app/com.wps.Office
Unit=wps-cloudsvr-mask.service

[Install]
WantedBy=multi-user.target

The .path unit watches the flatpak install directory itself … the moment an update touches it, it fires the mask service again, which resolves the new hash path and reapplies the mount. No manual intervention needed after a WPS update, ever.

Installing it

sudo ./install.sh

Copies the script to /usr/local/bin/, installs both units, enables them, and runs the mask once immediately to confirm it works … no waiting for the next boot or next update to see if it’s actually applied.

systemctl status wps-cloudsvr-mask.path wps-cloudsvr-mask-boot.service
mount | grep wpscloudsvr

The second command is the real proof … you should see /dev/null bind-mounted over the actual binary path.

Why bother with this much ceremony for one broken helper

Because the alternative was periodically noticing the crash reports again after every WPS update and re-doing this by hand. Once was tolerable. Solving it once, permanently, in a way that survives updates on its own, was worth the extra half hour of systemd unit writing.