跳转至

Crashpad 有界读取

崩溃后,Orca 会从可能很大的转储中提取简短的诊断签名。 旧读取器会加载完整转储。当前解析器通过四个保留的 64 KiB 页面读取有界范围, 并在大约 1 MiB 的窗口中扫描嵌入的诊断文本。 它可以捕获增长到超过现有 64 MiB 目录发现限制的报告, 而无需将该报告保存在一个大型缓冲区中。发现时已经超过该限制的报告 仍保留现有的排除策略。

复现

ORCA_BACKGROUND_LAUNCH=1 node docs/audits/crashpad-read-limit/reproduce.mjs

使用仓库中已安装的依赖项和受支持的 Node 版本。运行器在执行任何测试之前, 会检查 source-hashes.json 中已提交的 SHA-256 值。这包括 捕获/解析器、测试夹具、运行器及其本地导入,以及包和锁文件版本。 如果源已更改,它会拒绝继续,而不是静默记录新哈希。更新 清单需要审查更改的证据并重新运行证明。

运行器使用合成文件执行实际的捕获和文件源测试,然后 仅通过内存中的 Vite 转换禁用零大小范围截止时间,重复这些测试。 该变异不更改任何文件。这是针对截止时间的回归控制, 而不是对原始实现中所有行为的模拟。

阶段 通过 失败 跳过 退出
移除截止时间 24 2 0 1
当前实现 26 0 0 0

这两个预期失败验证了:一个报告为零大小的文件会在截止时间处停止读取, 即使仍有更多字节可用,也会在一页或两页之后停止。 控制项在观察到的范围和实际文件读取次数两方面都会失败。 运行器会检查它们的精确名称,并在出现意外结果时以失败状态退出。 results.json 记录已验证的哈希、计数、失败用例、退出代码和超时。

其他控制项覆盖 80 MiB 稀疏转储、超过 64 MiB 的元数据、标记/检查消息 边界、捕获期间的增长和替换、零大小增长、截断、描述符 清理以及部分头部重试行为。符号链接交换、已删除候选项或目录替换现在仅跳过该候选项;另一个有效转储仍可提供签名。在缺少 O_NOFOLLOW 的平台上,符号链接交换测试会被跳过。请求的最大解析器读取为 1 MiB + 4,096 字节,外加四个保留的 64 KiB 元数据页面。一个包含 1,042 个模块的夹具最多需要 八次读取,从而防止在模块页面和名称页面之间重复读取。

解析器兼容性

ORCA_BACKGROUND_LAUNCH=1 node docs/audits/crashpad-read-limit/stream-signature-parity.cjs

单独的一致性脚本将 47 个夹具与位于 09dbe227547fadaec8d9163f35fd127b0dc1c3ed 的已发布解析器进行比较, 同时使用内存缓冲区和真实文件句柄。 它覆盖注释、模块、异常、块边界和标记耗尽。它 还会打印 8/64 MiB 稀疏转储的五个预热计时;这些本地合成计时 不是全平台性能保证。这个较旧的一致性脚本不强制 源清单;请先使用带清单检查的回归运行器。

限制与用户影响

这消除了崩溃后可能很大的临时分配;它并未确定 常规会话 OOM 的原因,也未设置聚合进程内存上限。独立的捕获 可能重叠。没有证据将此文件增长竞态与 #19831 或 #19768 关联起来。

已打开的文件提供解析范围。就地重写不是原子快照。 非空文件保留其打开时的范围。以零大小打开的文件至少会接收一次 读取,然后仅观察到增长直到捕获截止时间;因此,后续字节可能 会从该诊断签名中省略。这可防止持续增长的报告 无限期地保持捕获打开。转储文件本身不会被此读取器截断。

Crashpad 通常先写入无效头部,之后再提升已完成文件: 数据库实现 和 minidump 写入器。 这些夹具表示该顺序;它们不会复现现场事故或原生 Crashpad 进程。所有检查都在没有应用窗口的后台 Node 进程中运行。

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