[Bug] Windows 非系统盘工作区在 workspace-write 下全部命令不可用:grantWrite 需要 WRITE_OWNER,而工作区目录默认没有 #7912
FalseLeonLai
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
摘要
在非系统盘用资源管理器新建一个普通文件夹作为工作区,切到
workspace-write后任何命令都无法执行(含Get-Location这类纯只读命令),报错发生在命令执行之前:read/write/edit工具不受影响;切到danger-full-access一切正常;稳定复现。严重级别:高——该模式在该类工作区下 100% 不可用。触发条件只是"在非系统盘建一个文件夹",属最主流用法。
环境
desktop,@deepseek-ai/dsh-sandbox-windows-acl0.1.7-alpha.2D:(非系统盘,Healthy),无 EFS 加密Administrators= group used for deny only)D:\project\AI\DSH4(资源管理器新建的空目录)workspace-write(sandbox=workspace-write, approval=ask)最小复现
workspace-write;Get-Location即可)→ 报上述错误;danger-full-access→ 正常;把工作区移到%USERPROFILE%下 →workspace-write也正常。第 4 步把变量锁死在「目录 ACL 继承」这一个因素上。
根因
packages/sandbox/sandbox-windows-acl/src/acl.ts的grantWrite对工作区目录做一次SetNamedSecurityInfoW调用,同时写入三样东西:FILE_DELETE_CHILD拒绝 ACE;写 SACL 中的完整性标签需要对象上的
WRITE_OWNER,仅WRITE_DAC不够。该包源码acl.ts:368-370已声明这个前提:但盘符根目录的默认 ACL 不满足。本机
D:\的继承权限:READ_CONTROL+WRITE_DACWRITE_OWNERWRITE_OWNERAuthenticated Users:(M)不含SeTakeOwnership被剥离→
ERROR_ACCESS_DENIED (5)。可写 DACL,不可写 SACL。诊断证据(对照组实验)
Set-Acl添加允许规则icacls /grant ...:(OI)(CI)M%USERPROFILE%)cipher加密属性U(未加密)决定性对比——同一进程、同一用户,仅目录位置不同:
%LOCALAPPDATA%\Temp\dsh-XXXX\(沙箱私有临时目录)D:\project\AI\DSH4(工作区目录)D:\→Authenticated Users:(M)同一份代码、同一个用户,差别只在目录位置带来的 ACL 继承差异。
补充发现:这个失败无法被前置发现
看起来探测本该拦住它,但 Windows 上两层都失效。
packages/sandbox/sandbox-local/src/index.ts的探测函数:它自己的注释写着:"run the runner in read-only mode (zero grants, no ACL mutation)"——即探测根本不走出问题的授权路径。
同时该文件的注释又写着:"The win32 chain is a sole candidate, so the product never probes",而
PLATFORM_CHAINS.win32 = ['windows-acl'],chainVerdict()对单候选直接返回{ runner: 'windows-acl', enforcement: 'partial' }。结果:链路被判定为健康,授权在第一条 workspace-write 命令时才在
sandbox-local的materializeAclGrant里懒物化并失败。用户拿到的是原始 Win32 错误,而不是SandboxUnavailableError——与沙箱「拒绝 / 不可用」的语义区分相反。缺陷清单
grantWrite的WRITE_OWNER前提只写在注释里,从不校验。sandbox-windows-acl/src/index.ts的构造函数仅校验存在性与目录类型:--mode read-only(零授权),且 win32 单候选链根本不探测。授权失败无法被前置发现。add()抛错 → 实例被 dispose(撤销全部可撤销授权)→ 模式整体不可用,无「警告后按较低保证运行」路径。%USERPROFILE%下成立,但工作区是任意路径,跨盘符时假定失效,而没有任何一层去建立它。建议修复
WRITE_OWNER,缺失则为当前用户补一条可继承的 FullControl ACE——该包本就具备修改 DACL 的能力。WRITE_OWNER,失败即判unusable,抛出SandboxUnavailableError而不是把原始 Win32 错误漏给用户。workspace-write 需要 <path> 授予 WRITE_OWNER:icacls "<path>" /grant "%USERNAME%:(OI)(CI)F"本机临时绕过(已验证)
注意
(M)(Modify)无效——Modify掩码不含WRITE_OWNER,必须用(F)。验证方式:修复后工作区内写入成功 且 工作区外写入被拒绝,两者同时成立才证明是
workspace-write模式在生效(否则可能只是停在danger-full-access)。未验证的推断
以下为推断,未实测:
hasExactGrant && hasExactDeny && hasExactLabel未命中而重新 apply,而非存在「仅改 DACL」的降级路径。依据:源码只有一条grantWrite路径。D:上实测。Administrators:(F)生效而消失。附注
Discussion #1312 的附件中也报告过 pwsh/sandbox 问题,但该帖的两条评论均只处理「子代理选模型」一项,并注明 pwsh/sandbox 不在其覆盖范围。因附件内容无法检索,无法确认是否与本问题细节一致,故单开此帖。
All reactions