From 55b65182d38676893a198551dddfb83290a0138d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 8 Mar 2026 13:42:35 +0000 Subject: [PATCH] fix: harden darwin restart landing (#39763) (thanks @daymade) --- CHANGELOG.md | 2 +- src/infra/process-respawn.test.ts | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b78de9fa2ce..172279f2fda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -725,7 +725,7 @@ Docs: https://docs.openclaw.ai ### Fixes -- Gateway/macOS restart: remove self-issued `launchctl kickstart -k` from launchd supervised restart path to prevent race with launchd's async bootout state machine that permanently unloads the LaunchAgent. With `ThrottleInterval=1` (current default), `exit(0)` + `KeepAlive=true` restarts the service within ~1s without the race condition. (#39760) Landed from contributor PR #39763 by @daymade. Thanks @daymade. +- Gateway/macOS restart: remove self-issued `launchctl kickstart -k` from launchd supervised restart path to prevent race with launchd's async bootout state machine that permanently unloads the LaunchAgent. With `ThrottleInterval=1` (current default), `exit(0)` + `KeepAlive=true` restarts the service within ~1s without the race condition. (#39760, #39763) Thanks @daymade. - Exec/system.run env sanitization: block dangerous override-only env pivots such as `GIT_SSH_COMMAND`, editor/pager hooks, and `GIT_CONFIG_` / `NPM_CONFIG_` override prefixes so allowlisted tools cannot smuggle helper command execution through subprocess environment overrides. Thanks @tdjackey and @SnailSploit for reporting. - Network/fetch guard redirect auth stripping: switch cross-origin redirect handling in `fetchWithSsrFGuard` from a narrow sensitive-header denylist to a safe-header allowlist so custom auth headers like `X-Api-Key` and `Private-Token` no longer leak on origin changes. Thanks @Rickidevs for reporting. - Security/Sandbox media reads: eliminate sandbox media TOCTOU symlink-retarget escapes by enforcing root-scoped boundary-safe reads at attachment/image load time and consolidating shared safe-read helpers across sandbox media callsites. This ships in the next npm release. Thanks @tdjackey for reporting. diff --git a/src/infra/process-respawn.test.ts b/src/infra/process-respawn.test.ts index 62091423af7..4052a408554 100644 --- a/src/infra/process-respawn.test.ts +++ b/src/infra/process-respawn.test.ts @@ -155,6 +155,27 @@ describe("restartGatewayProcessWithFreshPid", () => { expect(spawnMock).not.toHaveBeenCalled(); }); + it("returns failed when Scheduled Task restart helper fails on Windows", () => { + clearSupervisorHints(); + setPlatform("win32"); + process.env.OPENCLAW_SERVICE_MARKER = "openclaw"; + process.env.OPENCLAW_SERVICE_KIND = "gateway"; + triggerOpenClawRestartMock.mockReturnValue({ + ok: false, + method: "schtasks", + detail: "ERROR: Task not found.", + }); + + const result = restartGatewayProcessWithFreshPid(); + + expect(result).toEqual({ + mode: "failed", + detail: "ERROR: Task not found.", + }); + expect(triggerOpenClawRestartMock).toHaveBeenCalledOnce(); + expect(spawnMock).not.toHaveBeenCalled(); + }); + it("keeps generic service markers out of non-Windows supervisor detection", () => { clearSupervisorHints(); setPlatform("linux");