重写 Linux 基础工具,同时对照历史漏洞的实现与补丁。处理输入长度、释放资源或遇到错误时,代码依赖了哪些假设?哪些假设曾经导致过漏洞?这些问题可以带回自己的实现中检查。
目前整理了 58 条历史 CVE 记录,可以按工具模块找着读。资料位于学习分支的 draft PR,属于尚未逐例运行的阅读索引。下文介绍代码、补丁与实验的对照方法。
用模块连接材料
CVE 编号是检索入口。对实现更有帮助的线索通常是:问题发生在哪条代码路径,哪个假设失效了,以及补丁重新建立了什么条件。
| 阅读角度 | 实现时要明确的问题 |
|---|---|
| 长度与分块 | 长度使用什么类型?计算可能溢出吗?最后一个分块怎样处理? |
| 路径与权限 | 检查的是字符串还是最终对象?检查与使用之间有什么变化? |
| 归档与解包 | 文件名、链接与目标目录之间有哪些约束? |
| 资源生命周期 | 谁负责释放?部分失败后,状态是否仍一致? |
这些分类帮助寻找相似逻辑,但“模式相似”本身还不能证明一个实现存在漏洞。仍然需要核对具体语义、可到达条件和影响。
一条案例记录的证据
每条记录至少应该说明受影响版本、官方记录或公告、相关代码、修复提交,以及尚未验证的部分。
读补丁时,我会先尝试回答两个问题:修改之前代码依赖了什么条件?修改之后,这个条件是被检查、被重新建立,还是被换成了另一种设计?
如果这些问题暂时回答不了,就继续把它标记为阅读材料,而不把一段复现描述当成已经理解了根因。
将模式带回自己的实现
- 01 定义语义
- 02 对照假设
- 03 构造实验
- 04 回归验证
首先限定工具的功能子集,建立正常输入与边界输入下的预期行为。随后选择相关的历史失败模式,检查自己的实现是否依赖相似假设。
实验需要区分三个层次:历史问题是否复现、自己的实现是否存在同类条件、修改是否真正恢复了所需约束。它们各自需要证据,不能互相替代。
为什么先从 mini-split 开始
分块工具的接口相对小,却能触及计数、缓冲、文件命名和部分失败处理。限定功能后,输入与输出之间的关系容易检查,也适合积累第一组语义测试。
接下来先确定 mini-split 要支持哪些功能,写出预期行为和测试,再实现它。之后再读归档、路径、权限和资源生命周期的案例。每做一个实验,都把相关代码、遇到的问题和结果放在一起;如果改了代码,也要记下为什么改、怎样检查它。
索引将随着阅读继续扩充;记录数量和实际理解、复现的进度分别维护。
材料与来源
修订记录
- 记录历史案例索引与基础工具重实现之间的研究方法。