#!/usr/bin/env bash # 17-fix-rdp-postupdate.sh — re-apply RDP boot-survivability fixes (#611) # # After the 2026-09-05 update-reboot, fresh xrdp sessions died two ways: # # 1) sesman "waitforx: Timed out waiting for RandR outputs" -> "X server # could not be started" -> Jump shows error + black screen. # Root cause: xrdp 0.10.1 waitforx races xorgxrdp's deferred-RandR output # creation (~400ms after X start) and can go permanently blind; the # u2 security NMU also intermittently execs waitforx with EMPTY argv # (observed 2026-09-05 03:58:38) which the real binary rejects with a # usage error. FIX: wrapper at .../xrdp/waitforx that (a) defaults -d # from $DISPLAY when argv is empty, (b) forces a RandR query via # xrandr after the deferred window (deterministically materializes # outputs), then execs the pristine waitforx.real. # 2) /etc/X11/Xsession.d/90xbrlapi runs /bin/xbrlapi in the FOREGROUND; # with brltty inactive (no BrlAPI socket) it hangs forever, so Xsession # never reaches startplasma-x11 -> connected-but-black session. # FIX: disable the hook (no braille hardware on this VM). # # Also verifies (does not fight) the #611 baseline: max_bpp=24, # new_cursors=false (cursor black-box: Jump drops cursor alpha; core # shadowless cursors + server-side cursor drawing). # # Idempotent; safe while a session is live. --restart-xrdp bounces only # the front-end (sessions live in sesman/sesexec and survive). # # Usage: sudo ./17-fix-rdp-postupdate.sh [--restart-xrdp] # Self-elevates. Tee a run log: ./17-fix-rdp-postupdate.sh 2>&1 | tee logs/17-fix-rdp-postupdate.out set -euo pipefail [ "$(id -u)" = 0 ] || exec sudo bash "$0" "$@" WFX_DIR=/usr/lib/x86_64-linux-gnu/xrdp WFX=$WFX_DIR/waitforx XRDP_INI=/etc/xrdp/xrdp.ini XSDD=/etc/X11/Xsession.d LOG=${LOG:-/dev/stdout} say() { echo "[17-fix] $*"; } # --- 1. waitforx wrapper ------------------------------------------------- mkdir -p /var/log/xrdp-fix if [ ! -f "$WFX.real" ]; then cp -a "$WFX" "$WFX.real" say "backed up pristine waitforx -> $WFX.real" else say "pristine waitforx.real already present" fi cat > "$WFX" <<'SHIM' #!/bin/bash # xrdp 0.10.1 workaround (#611): default -d from DISPLAY when sesexec # passes empty argv; force a RandR query past the deferred-output window # before handing off to the real binary. Log to /var/log/xrdp-fix/. D=/var/log/xrdp-fix/waitforx-invocations.log echo "$(date '+%F %T') argc=$# argv:$(printf ' [%s]' "$@") DISPLAY=[$DISPLAY]" >> "$D" if [ $# -eq 0 ]; then set -- -d "${DISPLAY:-:10}" fi timeout 5 xrandr -display "${2:-${DISPLAY:-:10}}" >/dev/null 2>&1 || true exec /usr/lib/x86_64-linux-gnu/xrdp/waitforx.real "$@" SHIM chmod 755 "$WFX" bash -n "$WFX" || { say "FATAL: shim syntax error"; exit 1; } say "waitforx wrapper installed" # --- 2. xbrlapi foreground hang ------------------------------------------ if [ -f "$XSDD/90xbrlapi" ]; then mv "$XSDD/90xbrlapi" "$XSDD/90xbrlapi.disabled" say "disabled $XSDD/90xbrlapi (foreground xbrlapi hang, no braille HW)" else say "xbrlapi hook already disabled" fi # --- 3. xrdp.ini baseline ------------------------------------------------- grep -q '^max_bpp=24' "$XRDP_INI" || say "WARN: max_bpp=24 missing (expected from #611)" if grep -q '^new_cursors=true' "$XRDP_INI"; then sed -i 's/^new_cursors=true/new_cursors=false/' "$XRDP_INI" say "set new_cursors=false (cursor black-box fix)" else say "new_cursors already false (or absent)" fi # --- 4. optional front-end bounce ---------------------------------------- if [ "${1:-}" = "--restart-xrdp" ]; then systemctl restart xrdp say "xrdp front-end restarted (sessions unaffected)" fi say "done. Evidence: /var/log/xrdp-fix/ + /var/log/xrdp-sesman.log"