fix(desktop): provide a console for Windows ACL children - #629
Open
zp-home wants to merge 1 commit into
Open
Conversation
zp-home
force-pushed
the
fix/528-windows-workspace-write-console-host
branch
4 times, most recently
from
August 26, 2026 05:22
2d0374c to
fb7427f
Compare
zp-home
force-pushed
the
fix/528-windows-workspace-write-console-host
branch
from
August 26, 2026 16:26
fb7427f to
c3ef012
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
中文
摘要
在不修改上游 DSH ACL 沙箱的前提下,修复 #528、#305、#516、#439 所报告的 Windows Desktop
workspace-write故障。Electron 图形宿主及其 Node 模式 ACL 跳板进程启动时没有控制台。在受影响的 Windows 环境中,受限控制台子进程因此被迫在受限令牌生效后自行创建控制台,随后在
cmd.exe、PowerShell 或其他控制台程序开始执行前,就在 DLL 初始化阶段以0xC0000142(STATUS_DLL_INIT_FAILED)退出。本 PR 让经过精确校验的 Desktop 跳板进程在导入上游 ACL 运行器之前分配并隐藏控制台。受限子进程随后继承真实控制台,与拥有控制台的 CLI 宿主保持一致。
关联 Issue
Closes #528
Closes #305
Closes #516
Closes #439
相关替代方案 #266 会捆绑独立 Node 运行时,并说明 Windows 包体积约增加 87 MB。本 PR 保留现有 Electron RunAsNode 协议,只修复 #528 受控实验隔离出的控制台宿主差异,不会修改或关闭 #266。
类型与平台
复现
#528 记录的受影响环境:
workspace-write模式。复现步骤:
workspace-write。Write-Output hi或cmd.exe /c echo hi。3221225794,即0xC0000142返回,标准输出与标准错误均为空。#528 已记录的受控二分:
0xC0000142退出AttachConsole(-1)DETACHED_PROCESSAllocConsole()本机复现限制
开发机为 Windows 11
10.0.26200.0、x64、中完整性级别(S-1-16-8192)、Electron 43.4.0。它确认 Electron 图形运行器启动时没有控制台,但未修复的 Desktop v2.0.1 与旧 master 都能由 Windows 为受限子进程创建控制台并正常退出。因此,本 PR 不会声称已经在本机自然复现原始崩溃码。根因结论来自 #528 的受影响高完整性环境矩阵与受控宿主控制台二分。发布前仍需在受影响机器与真实打包产物上完成最终冒烟测试。
根因
上游 ACL 运行器有意省略
CREATE_NO_WINDOW和CREATE_NEW_CONSOLE,因为任一标志都可能使受限子进程在 DLL 初始化阶段失败。CLI 路径之所以正常,是因为子进程会继承 CLI 宿主控制台。失败顺序:
修复顺序:
修复
windows-console-host.ts,通过延迟加载的 Koffi 绑定调用GetConsoleWindow、AllocConsole、GetLastError和ShowWindow。SW_HIDE隐藏。windows-acl-run签名与退出码 127。与最新 master 的合并
本分支已 rebase 到
master@681ba66091fc5b1e827650137f69b3ee4c435922。冲突来自最新 master 新增的 Windows ACL relay/ConPTY 路径。合并结果保留了 relay payload 解码、runner 身份校验、relay 环境清理和参数恢复,并在身份校验成功后、参数恢复与上游 import 前执行ensureWindowsConsoleHost()。最终 head 为
c3ef012dfe2acf7e2cba02560715ee5663477c32,相对 master 为ahead 1 / behind 0,GitHub 状态为CLEAN / MERGEABLE。安全边界与副作用
以下行为没有改变:
deepseek-harness子模块与上游@deepseek-ai/dsh-sandbox-windows-acl。danger-full-access、普通 Node、macOS 和 Linux 路径。失败与生命周期行为:
AllocConsole()失败时保持安全关闭,不会在缺少 confinement 的情况下执行。SW_HIDE之间理论上可能出现极短闪现;原生探针观察到继承的控制台处于隐藏状态。验证
基于
master@681ba66的 rebase 后验证:corepack yarn install --immutable:通过,仅有仓库既有 peer dependency 警告。20/20通过。corepack yarn workspace dsh-plugin-desktop check:win-package:13 个文件,230/230通过。corepack yarn check:layout:通过,上游子模块b150a551b8一致。corepack yarn check:bilingual-docs:44 条记录、88 份文档一致。corepack yarn typecheck:通过。git diff --check origin/master...HEAD:通过。首次运行 Windows package gate 时,工作树的安装态仍来自 rebase 前基线,最新 master 新增的 settings icon Yarn patch 尚未链接到
node_modules,因此 package marker 断言失败,其他229/230通过。执行 immutable install 后重跑,230/230全部通过。本次 rebase 后未重新运行完整
corepack yarn check或真实安装包冒烟。旧 head 的远程 CI 曾全部通过;新 head 的 CI 由本次 push 重新触发。既有原生验证证据
旧 head 在真实 Electron GUI runner 与真实 ACL runner 上得到以下结果;本次 rebase 未重跑该人工矩阵:
cmd.exe /c echoELECTRON_GUI_OKELECTRON_GUI_OKCHILD_CONSOLE_PRESENTCHILD_CONSOLE_HIDDENINSIDE_OK,文件内容成功写入OUTSIDE_DENIED,外部文件不存在剩余发布门禁
合并或发布前,需要在 #528 的受影响高完整性 Windows 机器以及真实安装包或便携版产物上重跑矩阵。验收要求是:
cmd与 PowerShell 正常退出、标准输出和标准错误可捕获、没有可见控制台、工作区内写入成功、外部写入拒绝,并且没有 ACL 残留。发布说明
Windows Desktop 的
workspace-write现在会为受限控制台工具提供隐藏且可继承的控制台,从而避免受影响机器上的0xC0000142启动失败,同时不削弱 ACL confinement。用户不需要迁移或修改配置。English
Summary
Fix the Windows Desktop
workspace-writefailure reported in #528, #305, #516, and #439 without changing the upstream DSH ACL sandbox.The Electron GUI host and its Node-mode ACL trampoline start without a console. On affected Windows environments, the restricted console child is consequently forced to create its own console after the restricted token is active. DLL initialization then exits with
0xC0000142(STATUS_DLL_INIT_FAILED) beforecmd.exe, PowerShell, or another console program can run.This PR makes the validated Desktop trampoline allocate and hide a console before importing the upstream ACL runner. The restricted child then inherits a real console, matching the console-hosted CLI assumption.
Related Issues
Closes #528
Closes #305
Closes #516
Closes #439
Related alternative #266 bundles an independent Node runtime and reports an approximately 87 MB Windows package increase. This PR keeps the existing Electron RunAsNode protocol and addresses the narrower console-host mismatch isolated by #528. It does not modify or close #266.
Type And Platforms
Reproduction
Affected environment recorded by #528:
workspace-writemode.Reproduction steps:
workspace-write.Write-Output hiorcmd.exe /c echo hi.3221225794/0xC0000142with empty stdout and stderr.Controlled bisection recorded in #528:
0xC0000142on the affected hostAttachConsole(-1)DETACHED_PROCESSAllocConsole()Local Reproduction Limit
The development machine is Windows 11
10.0.26200.0, x64, Medium integrity (S-1-16-8192), Electron 43.4.0. It confirms that the Electron GUI runner starts without a console, but both unpacked Desktop v2.0.1 and the old pre-fix master allowed Windows to create the restricted child's console and exited 0. This PR therefore does not claim that the original crash code was reproduced naturally on the development machine.The root-cause claim relies on #528's affected high-integrity matrix and controlled host-console bisection. A final affected-host and packaged-artifact smoke remains required before release.
Root Cause
The upstream ACL runner intentionally omits
CREATE_NO_WINDOWandCREATE_NEW_CONSOLE; either flag can make restricted children fail DLL initialization. This works for CLI because the child inherits the CLI host console.Failure sequence:
Repaired sequence:
Fix
windows-console-host.tswith lazily loaded Koffi bindings forGetConsoleWindow,AllocConsole,GetLastError, andShowWindow.SW_HIDEwhen one is available.windows-acl-runsignature plus exit 127.Integration With Current Master
The branch is rebased onto
master@681ba66091fc5b1e827650137f69b3ee4c435922. The conflict came from the Windows ACL relay/ConPTY path added on current master. The resolution preserves relay payload decoding, runner identity validation, relay-environment cleanup, and argument restoration. It invokesensureWindowsConsoleHost()after successful identity validation and before argument restoration and the upstream import.The final head is
c3ef012dfe2acf7e2cba02560715ee5663477c32. It isahead 1 / behind 0, and GitHub reportsCLEAN / MERGEABLE.Security Boundary And Side Effects
The following behavior is unchanged:
deepseek-harnesssubmodule and upstream@deepseek-ai/dsh-sandbox-windows-acl.danger-full-access, plain Node, macOS, and Linux paths.Failure and lifecycle behavior:
AllocConsole()failure fails closed instead of executing without confinement.SW_HIDE; the native probe observed the inherited console as hidden.Verification
Post-rebase verification on
master@681ba66:corepack yarn install --immutable: passed with existing peer dependency warnings only.20/20passed.corepack yarn workspace dsh-plugin-desktop check:win-package: 13 files,230/230passed.corepack yarn check:layout: passed; upstream submoduleb150a551b8is consistent.corepack yarn check:bilingual-docs: 44 records and 88 documents are consistent.corepack yarn typecheck: passed.git diff --check origin/master...HEAD: passed.The first Windows package gate run used the pre-rebase installation state, so the settings icon Yarn patch added by current master was not linked into
node_modules. Its package marker assertion failed while the other229/230tests passed. After the immutable install, the rerun passed230/230.The complete
corepack yarn checkand a real packaged-artifact smoke were not rerun after this rebase. Remote CI passed on the old head; the force-push triggers CI again for the new head.Existing Native Evidence
The old head produced the following results with the real Electron GUI runner and real ACL runner. This manual matrix was not rerun after the rebase:
cmd.exe /c echoELECTRON_GUI_OKELECTRON_GUI_OKCHILD_CONSOLE_PRESENTCHILD_CONSOLE_HIDDENINSIDE_OK, file content writtenOUTSIDE_DENIED, no outside fileRemaining Release Gate
Before merge or release, rerun the #528 matrix on the affected high-integrity Windows host and a packaged installer or portable artifact. Acceptance requires normal
cmdand PowerShell exit, captured stdout and stderr, no visible console, successful workspace writes, denied outside writes, and no ACL residue.Release Notes
Windows Desktop sessions using
workspace-writenow provide restricted console tools with a hidden inherited console, avoiding the affected-host0xC0000142startup failure without weakening ACL confinement. No migration or configuration change is required.