From 04bcabcbae66b6c322f192e1265d817b14c290cf Mon Sep 17 00:00:00 2001 From: junwon <153147718+junjunjunbong@users.noreply.github.com> Date: Tue, 24 Feb 2026 12:33:27 +0900 Subject: [PATCH] fix(infra): handle Windows dev=0 in sameFileIdentity TOCTOU check (#24939) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(infra): handle Windows dev=0 in sameFileIdentity TOCTOU check On Windows, `fs.lstatSync` (path-based) returns `dev: 0` while `fs.fstatSync` (fd-based) returns the real NTFS volume serial number. This mismatch caused `sameFileIdentity` to always fail, making `openVerifiedFileSync` reject every file — silently breaking all Control UI static file serving (HTTP 404). Fall back to ino-only comparison when either dev is 0 on Windows. ino remains unique within a single volume, so TOCTOU protection is preserved. Fixes #24692 * fix: format sameFileIdentity wrapping (#24939) --------- Co-authored-by: Peter Steinberger --- src/infra/safe-open-sync.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/infra/safe-open-sync.ts b/src/infra/safe-open-sync.ts index ac4638483..f2dbdfb70 100644 --- a/src/infra/safe-open-sync.ts +++ b/src/infra/safe-open-sync.ts @@ -17,7 +17,12 @@ function isExpectedPathError(error: unknown): boolean { } export function sameFileIdentity(left: fs.Stats, right: fs.Stats): boolean { - return left.dev === right.dev && left.ino === right.ino; + // On Windows, lstatSync (by path) may return dev=0 while fstatSync (by fd) + // returns the real volume serial number. When either dev is 0, fall back to + // ino-only comparison which is still unique within a single volume. + const devMatch = + left.dev === right.dev || (process.platform === "win32" && (left.dev === 0 || right.dev === 0)); + return devMatch && left.ino === right.ino; } export function openVerifiedFileSync(params: {