From 9ff572cc8bbb227b280ef17feabdbf0b8d8e780a Mon Sep 17 00:00:00 2001 From: gwatkins Date: Mon, 24 Aug 2026 10:35:43 -0700 Subject: [PATCH] fix(linux): skip creating host stubs for non-existent deny paths When a deny path does not exist on disk, bwrap cannot bind-mount over it without creating an empty stub file on the host. These empty files pollute working directories with 0-byte ghost dotfiles (.bashrc, .zprofile, .mcp.json, etc.) and cause race conditions (Permission denied) when multiple sandboxed commands execute concurrently. 1. In linuxGetMandatoryDenyPaths, only add dangerous files and directories in CWD if they actually exist on disk. 2. In generateFilesystemArgs, skip --ro-bind /dev/null for non-existent leaf deny paths instead of mounting over created host stub files. --- src/sandbox/linux-sandbox-utils.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/sandbox/linux-sandbox-utils.ts b/src/sandbox/linux-sandbox-utils.ts index e31685cfe..c784a614b 100644 --- a/src/sandbox/linux-sandbox-utils.ts +++ b/src/sandbox/linux-sandbox-utils.ts @@ -286,10 +286,12 @@ async function linuxGetMandatoryDenyPaths( // Note: Settings files are added at the callsite in sandbox-manager.ts const denyPaths = [ - // Dangerous files in CWD - ...DANGEROUS_FILES.map(f => path.resolve(cwd, f)), - // Dangerous directories in CWD - ...dangerousDirectories.map(d => path.resolve(cwd, d)), + // Dangerous files in CWD - only protect if they actually exist on disk. + // Non-existent dangerous files should NOT have host mount points created for them, + // which would pollute the working directory with 0-byte ghost dotfiles. + ...DANGEROUS_FILES.map(f => path.resolve(cwd, f)).filter(p => fs.existsSync(p)), + // Dangerous directories in CWD - only protect if they exist + ...dangerousDirectories.map(d => path.resolve(cwd, d)).filter(p => fs.existsSync(p)), ] // Git hooks and config are only denied when .git exists as a directory. @@ -1398,12 +1400,11 @@ async function generateFilesystemArgs( `[Sandbox Linux] Mounted empty dir at ${firstNonExistent} to block creation of ${normalizedPath}`, ) } else { - denyWriteArgs.push('--ro-bind', '/dev/null', firstNonExistent) - denyWriteRawDests.set(firstNonExistent, rawPath) - bwrapMountPoints.add(firstNonExistent) - registerExitCleanupHandler() + // Do not create empty files on the host for non-existent leaf deny paths. + // Creating host stub files for missing paths pollutes the repository with ghost + // dotfiles and causes race conditions with concurrent bwrap instances. logForDebugging( - `[Sandbox Linux] Mounted /dev/null at ${firstNonExistent} to block creation of ${normalizedPath}`, + `[Sandbox Linux] Skipping non-existent leaf deny path to avoid creating host ghost files: ${normalizedPath}`, ) } } else if (ancestorIsWithinReadOnlyDeny) {