fix(worktree): refuse the drvfs volume root and the automount under a WSL UNC alias

`\\wsl.localhost\Ubuntu\mnt\c` is the whole C: volume and `\\wsl.localhost\Ubuntu\mnt`
holds every drvfs volume. Neither is caught by the root check in
`isDangerousWorktreeRemovalPath` (their win32 root is the distro share) nor by the
Windows-profile rule on the drive form (`C:\` is not `C:\Users`), so both read as
deletable. Measured on a Windows 11 host with WSL2: `rm -rf` inside the distro on the
`/mnt/c` spelling deletes on the Windows drive.
This commit is contained in:
Neil
2026-09-20 22:46:35 -07:00
parent 2ca2b008fc
commit 4a7a835c0f
2 changed files with 14 additions and 2 deletions
@@ -93,7 +93,12 @@ describe('path-shape home detection', () => {
// `C:\Users\bob` wearing a Linux spelling, not a directory in the distro.
['\\\\wsl.localhost\\Ubuntu\\mnt\\c\\Users\\bob', true],
['\\\\wsl$\\Ubuntu\\mnt\\c\\Users', true],
// The volume itself, and the automount that holds every volume, contain the profile.
['\\\\wsl.localhost\\Ubuntu\\mnt\\c', true],
['\\\\wsl.localhost\\Ubuntu\\mnt\\c\\', true],
['\\\\wsl.localhost\\Ubuntu\\mnt', true],
['\\\\wsl.localhost\\Ubuntu\\mnt\\c\\Users\\bob\\ws\\wt', false],
['\\\\wsl.localhost\\Ubuntu\\mnt\\c\\src\\repo', false],
// `/MNT` is an ordinary case-sensitive Linux directory, never the automount.
['\\\\wsl.localhost\\Ubuntu\\MNT\\c\\Users\\bob', false]
])('WSL drvfs %s -> %s', (worktreePath, expected) => {
+9 -2
View File
@@ -189,9 +189,16 @@ function isLikelyWslDistroHomeDirectory(resolvedWorktreePath: string, pathOps: P
const linuxPath = trimTrailingSlash(wsl.linuxPath)
const drivePath = toWindowsWslDrivePath(linuxPath)
if (drivePath) {
return isLikelyWindowsUserProfileDirectory(win32.resolve(drivePath), win32)
const resolvedDrivePath = win32.resolve(drivePath)
// Why: `/mnt/c` is the whole volume. `C:\` is refused as a root before this guard runs; its
// drvfs spelling has to be refused here, since its win32 root is the distro share.
return (
win32.parse(resolvedDrivePath).root === resolvedDrivePath ||
isLikelyWindowsUserProfileDirectory(resolvedDrivePath, win32)
)
}
return wsl.linuxPath === '/' || isPosixHomeRoot(linuxPath)
// Why `/mnt`: the automount parent holds every drvfs volume, so it contains every profile.
return wsl.linuxPath === '/' || linuxPath === '/mnt' || isPosixHomeRoot(linuxPath)
}
function isWslUncRemovalPath(resolvedWorktreePath: string): boolean {