dm-verity is a Linux device mapper target, available since kernel 3.4, that provides transparent read-only integrity verification for block devices. When a block device is mapped through dm-verity, every data block read from the underlying device is verified against a pre-computed Merkle tree of cryptographic hashes before being returned to the caller — any modification to any block, whether from corruption, bit rot, or deliberate tampering, produces a hash mismatch that dm-verity detects and handles according to its configured error mode. The verification is transparent to the filesystem and applications mounted above it: they read from the dm-verity device as if it were a normal block device, with no awareness that every read is being hash-checked. The security guarantee is that the integrity of the entire block device is committed to by a single root hash — a 32-byte SHA-256 value that covers the entire Merkle tree and therefore the entire data volume. If the root hash is known to be correct (because it was measured into a TPM PCR, embedded in a UKI, or signed by a Secure Boot key), then any verified read from the dm-verity device is guaranteed to return exactly the data that was present when the Merkle tree was computed.
The Merkle tree structure makes verification efficient. The data blocks are divided into fixed-size chunks (4096 bytes by default, matching the typical filesystem block size); each chunk’s SHA-256 hash forms a leaf node. Leaf hashes are concatenated in groups and hashed again to form the next tree level, continuing until a single root hash remains. The hash tree itself is stored in a separate contiguous region on the same device (or on a separate device), and dm-verity caches recently verified hash blocks in memory, so the amortised cost of verification is dominated by a small number of tree-level hash reads per data block access rather than a full tree traversal. The veritysetup format command (from cryptsetup) computes the hash tree and returns the root hash; veritysetup create establishes the dm-verity device mapping with the root hash as a parameter that the kernel verifies at mount time against the stored tree. Once established, the dm-verity mapping is read-only and the root hash is fixed — any attempt to write through it is rejected. Error handling offers three modes: ignore (pass the corrupted data to the caller and log), restart (trigger a kernel panic and reboot, used in production Android and Chrome OS), and panic (immediate kernel panic). Production deployments universally use restart or panic because ignore defeats the security model.
dm-verity is the block-level integrity primitive that enables verified, immutable OS deployments at scale. In Android Verified Boot, the system and vendor partitions are dm-verity protected with root hashes stored in the boot partition and measured into the boot attestation chain — modifying a system file produces a hash mismatch that causes the device to refuse to boot into a verified state. In Chrome OS, all OS partitions are dm-verity protected, with the root hash embedded in the read-only firmware; updates replace the entire partition and recompute the tree. In bootc-based image Linux deployments, dm-verity complements composefs: dm-verity protects the block device layer where the OSTree object store lives, while composefs provides the file-level verified overlay on top. The key difference between dm-verity and fs-verity is their layer of operation: dm-verity operates below the filesystem, protecting arbitrary block devices, and cannot share data between images (two dm-verity volumes containing the same file use separate, non-shared blocks); fs-verity operates at the individual file level within a filesystem, enabling the per-file content addressing and sharing that composefs uses. dm-verity’s performance cost is minimal on sequential reads (hash tree levels are cached) but is more noticeable on random small-block I/O workloads where cache miss rates are higher — SSD-backed deployments typically see less than 5% overhead; spinning-disk deployments can see 10–20% on random workloads.
