fs-verity:文件边读边验,怎样发现磁盘内容被改过?
TL;DR
fs-verity 使用 Merkle 哈希树在文件读取时检查内容完整性。本文解释它如何验证单个只读文件、为什么根哈希仍需要可信来源,以及它和面向块设备的 dm-verity 有何不同。
fs-verity 使用 Merkle 哈希树在文件读取时检查内容完整性。本文解释它如何验证单个只读文件、为什么根哈希仍需要可信来源,以及它和面向块设备的 dm-verity 有何不同。

下载完成的文件如果在磁盘上被意外改写,系统能否在应用读取时发现?fs-verity 提供了一种面向单个文件的完整性验证机制:它为只读文件建立 Merkle 哈希树,之后读取内容时逐层核对数据是否与树中的哈希一致。
先从哈希说起。哈希函数会把一段数据变成固定长度的摘要;数据只改动一个比特,摘要通常就会不同。Merkle 树则把很多小块的哈希组合起来,再不断向上汇总,最终得到一个根哈希。验证某个数据块时,不必把整份文件全部读完,只需检查该块及其通往根节点的那条路径。fs-verity 利用这种结构,把文件内容与根哈希绑定起来。
启用后,文件系统可以在数据页进入内存时验证其完整性。如果底层存储数据意外损坏或被篡改,验证就会失败,而不是把未经确认的内容悄悄交给应用。因为树结构允许局部证明,这种方式适合体积较大、读取位置不固定的文件,例如应用包、系统镜像中的单个文件或经验证的静态资源。
不过,完整性验证不等于“确认是谁发布的”。fs-verity 能告诉你读取到的文件是否符合某个根哈希,却不能单独证明这个根哈希来自可信开发者。如果攻击者能同时替换文件和系统信任的根哈希,校验仍可能通过。通常还需要数字签名、可信的软件分发链或由系统管理的哈希清单,来回答“应该相信哪个根哈希”。
它也不等同于 dm-verity。fs-verity 面向单个文件,允许在文件系统中逐文件启用;dm-verity 则主要在块设备或只读文件系统层面验证数据。两者使用 Merkle 树的思路相近,但保护对象、配置方式和使用场景不同。理解这个差别有助于判断完整性策略应该放在文件级还是整块存储级。
还有一个重要前提:启用验证的文件按设计是不可随意修改的。若应用要更新内容,通常要以新的受验证文件替换旧版本,而不是原地改变已保护文件。总体而言,fs-verity 把“读到的内容是否还是原来那份”变成了内核可检查的问题;要建立真正的信任,还要把校验结果与可靠的签名和更新流程连接起来。



