Filesystem Integrity
Integrity verification on every startup — and every read after that.
See Filesystem verity in the developer reference for the image.verity opt-in on the rootfs and on extensions.
Avocado OS can protect the root filesystem and individual extensions with dm-verity, giving continuous block-level integrity verification rather than a single check at boot: dm-verity intercepts every filesystem read and verifies each block against a pre-computed Merkle hash tree.
Any modification to the filesystem — whether from a malicious actor, a cosmic ray flipping bits in storage, or silent disk corruption — is detected at read time. If a block doesn't match its expected hash, the read fails rather than silently executing corrupted code.
Verity is enabled per image with image.verity rather than being on by default, and on the rootfs it additionally needs a target that can carry the root hash in a boot FIT — see Filesystem verity for which machines qualify today. Everything below describes how it behaves once enabled.
How it works
Immutable root filesystem
The Avocado root filesystem is a read-only image. Nothing at runtime can modify it — there is no writable root. This is the foundation that makes dm-verity practical: you can compute a complete hash tree at build time because the filesystem will never change.
Root filesystem
├── Read-only mount
├── dm-verity hash tree computed at build time
└── Every block verified on read against Merkle tree
Merkle hash tree
At build time, Avocado computes a cryptographic hash for every block in the root filesystem. These hashes form a Merkle tree — a binary tree where each parent node is the hash of its children. The root hash of this tree is a single value that represents the integrity of the entire filesystem.
This root hash is signed and embedded in the boot chain. When the kernel mounts the root filesystem with dm-verity enabled, it uses this root hash to verify every subsequent block read. Verifying any single block requires walking the tree from that block up to the root — a fast, constant-depth operation.
Extension verification
Avocado's system extensions (sysext) and configuration extensions (confext) each carry their own independent hash trees. This means:
- Each extension is verified independently of the base system
- A corrupted extension doesn't require re-verifying the entire OS
- Extensions can be updated, added, or removed without affecting the integrity of other components
- Rollback to a previous extension version restores a known-good, verified state
What happens on verification failure
When dm-verity detects a block that doesn't match its expected hash:
- The read operation returns an I/O error
- The system logs the failure with the specific block that failed verification
- Depending on configuration, the system can continue in degraded mode or trigger a reboot into the recovery partition
- On reboot, the A/B partition scheme allows falling back to the last known-good slot
Relationship to secure boot
dm-verity and secure boot are complementary layers:
- Secure boot ensures that only authorized code starts executing — it validates the chain from silicon through bootloader through kernel.
- dm-verity ensures that the filesystem the kernel reads from hasn't been modified — it validates every block, every time it's read.
Together, they create a continuous verification chain: secure boot trusts the kernel, the kernel trusts the dm-verity root hash, and dm-verity verifies every block of the root filesystem and every extension overlay.
No runtime overhead in practice
dm-verity verification is a hash comparison on each block read. On modern hardware with hardware-accelerated cryptography, this adds negligible latency. Blocks are verified on first read and cached — subsequent reads of the same block hit the page cache without re-verification. For embedded workloads, the performance impact is effectively zero.