v4.169.44 - Windows exec and restart lifecycle hardening
v4.169.44 — Windows exec and restart lifecycle hardening
This hotfix follows a live memory incident discovered after v4.169.43.
Root cause
The 44.5 GiB process was not Book of Eternity's client, daemon, ConPTY bridge, or terminal relay. It was an agent-authored PowerShell diagnostic sent through /v1/exec/script. Deep ConvertTo-Json recursively serialized the extended metadata carried by Get-Content objects. The request timed out after 90 seconds, but Windows cleanup killed only its cmd.exe shell; the PowerShell child survived for roughly three hours and accumulated 44,521.9 MB private bytes and 6,672 CPU-seconds.
Fixes
- Windows exec timeout now uses
taskkill.exe /PID <pid> /T /F, with direct kill as fallback. - Buffered and streaming runners kill and reap still-running children during cancellation, disconnect, and orderly shutdown.
- Streaming pump tasks are cancelled and awaited during abnormal teardown.
- Manual
/v1/admin/update/restartnow arms a detached WSH/CMD helper before exit, waits for the old PID, tries VBS/batch/task launchers, and verifies the port. - Restart is refused without shutting down when the helper cannot be armed.
- Windows auto-update reuses its existing mover instead of racing a second relaunch helper.
Validation
- 8,320 tests collected; bare full suite and
preflight.py --fullpassed. - Coverage: 63.07% lines / 51.65% branches.
- Bandit 0 high/medium; Semgrep 0 findings; pip-audit 0 known vulnerabilities.
- Live timeout sabotage: HTTP 408 at 3.174s; PowerShell parent PID 4552 and nested child PID 2848 were both gone; zero script orphans.
- Live manual restart: endpoint returned
relauncherPrepared=true; detached log reportedready via start_hidden.vbs; health returned automatically. - Post-sabotage memory sample: no retained process above 96.4 MB private; daemon, ConPTY, and terminal relay had zero growth.