跳转至

保留在滚动积压之后的已完成 SSH 写入

SSH 多路复用器通道调度器推进了读取索引,但未清除已消费条目。保持非空的通道会保留每个已完成的 WriterEntry、其编码缓冲区及其结算回调。写入器已将这些条目从其字节和帧计数器中释放,因此准入限制不会约束这个已消费前缀。完全排空该通道或释放多路复用器会释放它。

修复会清除选中的槽位,并在至少 1,024 次选择后,如果已消费前缀占据数组至少一半,则对其进行压缩。这遵循现有 RelayFrameBuffer 模式。通道顺序、公平性、准入限制、传输结算和在途所有权均保持不变。clear() 仅返回剩余的活动条目。

实际调用方与所有权

普通通道验证执行 writeToSshPtyWithSettlement → SshChannelMultiplexer.notifyWithSettlement → SshMultiplexerTransportWriter → SshMultiplexerWriterLaneScheduler。SshPtyProvider 通过其 RPC 操作暴露相同辅助函数。控制通道验证使用由 requestGitStreamable 发出的 git.responseAck 通知形状。

ssh-relay-deploy-helpers.ts 将传输写入和结算回调连接到 channel.stdin.write,并注册其 drain 事件。一个在反复背压/排空周期中始终保留至少一个排队条目的生产者会达到保留前缀状态。该验证覆盖受控回调/排空端口,以及具有延迟写入回调和合成 16 KiB 高水位标记的真实 Node Writable。不会启动 SSH 连接、应用、窗口或远程进程。

选择条目会将调度器控制权转移到写入器的在途集合。清除其已消费队列槽位不会完成写入。一个单独的控制操作在存在一个在途写入和一个排队写入时执行释放:它们现有的结果分别保持为 unverifiable 和 refused。原生回调仍可能保留在途缓冲区,直到该回调引用被释放。迟到和重复回调不会将其结算两次。

结果

两个捕获的运行时产生相同计数:Node 26.6 和 Electron 43.7 / Node 24.21。每个在修复前后各运行六个场景。

受控暂停时的场景 原始 修复后
普通通道:保留的已完成缓冲区和结算回调 各 2,048 0
控制通道:保留的已完成缓冲区和结算回调 各 2,048 0
这些选择后的物理队列槽位 2,050 2
逻辑排队的普通帧 / 字节 2 / 706 2 / 706
逻辑排队的控制帧 / 字节 2 / 184 2 / 184
真实可写对象:保留的已写入缓冲区(包括一个在途) 128 1
原生回调仍被持有时,释放后保留的在途缓冲区 1 1
完全排空或最终回调释放后保留的已写入缓冲区 0 0

真实可写对象场景完成 128 次写入,启动第 129 次,并保留另外两次写入排队。第一次写入早于滚动积压,并且在两个变体中都可回收;因此原始版本保留 127 个已完成缓冲区加上一个在途缓冲区。其逻辑预算在两个变体中均为三帧 / 49,440 字节。低于压缩阈值的空槽位是预期行为,并且不会保留这些缓冲区。

场景断言 FIFO 顺序、普通/控制计数器的隔离、完全排空和释放清理。五个永久性生命周期回归测试加上 26 个现有测试通过。原始源代码覆盖层失败于四个滚动积压回归测试,并通过其他 27 个测试。现有测试覆盖控制优先级和饥饿预防、存活绕过、同步排空、回调错误和重复、溢出、释放、超时以及慢但存活的传输处理。参见 validation.json 了解命令和完整发布质量检查。

复现

在依赖安装后,从仓库根目录执行:

ORCA_BACKGROUND_LAUNCH=1 node --expose-gc --max-old-space-size=192 docs/audits/ssh-writer-consumed-prefix/reproduce.cjs

对于 Electron,使用 ELECTRON_RUN_AS_NODE=1 和 ORCA_BACKGROUND_LAUNCH=1 运行已安装的 Electron 可执行文件,并传入相同的标志和脚本路径。这是一个无 UI 的 Node 模式进程。运行器有 20 秒截止时间。

可选的最终参数选择报告目标,例如 notes/ssh-writer-consumed-prefix/reviewer-node.json。如果没有,运行器会刷新对应工件 node-results.json 或 electron-results.json。

sources.cjs 在内存中反转 fix.patch,并验证原始和修复后的 SHA-256 哈希。它还根据记录的哈希验证全部九个捆绑源依赖。不会重写任何源文件。对补丁和源代码进行合成的 CRLF 读取,必须复现相同的规范化 LF 源代码和哈希。before.config.mjs 对原始源代码测试覆盖层使用相同的源加载器。

源代码兼容性与范围

source-versions.json 记录修复前审计提交处的精确调度器基线、独立 main 291b4ddd6f1c1af480169885e0fda7f9c78ff053 以及 v1.4.198 e0826956fcfc532f5a1e55b5e081f2e57e553c43。这些调度器源代码在 LF 规范化后逐字节相同,因此相同补丁产生相同的修复后哈希。全部九个捆绑源代码和三个额外调用方源代码与独立 main 匹配。预期的 main 变更不依赖于其他内存审计修复。

v1.4.198 调度器相同,其写入器包含相同的入队/选择/释放路径。十二个依赖/调用方文件中有七个与当前源代码不同;此工件不声称执行打包的历史发布。

输入和时序是受控夹具。可达性计数确立了代码级保留机制;它们不测量受影响主机的 RSS,不建模报告的增长率,也不确立某次事件具有持续非空的 SSH 写入通道。活动待处理写入、传输层拥有的回调以及保留的原始序列时间戳仍受其现有限制和生命周期约束。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 orca48/orca