AOSP Foundations
3 min read

dm-verity

A technical dive into the kernel driver that performs on-the-fly, block-level cryptographic verification of the system partitions.

Verifying a small 30MB boot.img during startup is incredibly fast and easy. The bootloader calculates the SHA-256 hash of the file in RAM and checks it against the vbmeta partition in milliseconds.

However, the /system and /vendor partitions are massive (often exceeding 4GB to 8GB). If the bootloader attempted to read and hash an entire 8GB partition every time you turned on your phone, booting would easily take 5 to 10 minutes.

To solve this, Android Verified Boot utilizes a powerful Linux kernel feature called dm-verity.

On-the-Fly Block Verification

Instead of verifying the entire partition during the bootloader stage, dm-verity (Device Mapper Verity) verifies the partition continuously, on-the-fly, while the phone is actively running in the background.

  1. The Virtual Block Device: When the init process mounts the /system partition, it doesn't mount it directly. It asks the dm-verity kernel driver to securely place a transparent virtual mapping over the partition.
  2. Intercepting Reads: Every single time an app or service tries to read a file from the /system partition, the request passes through the dm-verity driver.
  3. Block Hashing: The dm-verity driver intercepts the specific 4KB block of data being read from the physical flash chip. It instantly calculates the cryptographic hash of that specific 4KB block and mathematically compares it against a known, absolutely trusted hash.

If the hashes perfectly match, the driver passes the data to the app. If the hashes do NOT match, it means a piece of malware (or a physically corrupt flash memory chip) has altered that specific byte of the operating system.

# Developers with root can temporarily disable verity for testing purposes
adb disable-verity
adb reboot

The Hash Tree

How does dm-verity instantly know the correct hash for every single 4KB block on a massive 4GB partition? It uses a cryptographic structure called a Merkle Tree (Hash Tree).

  • During the AOSP compilation process, the build system calculates the hash of every single 4KB block.
  • It then mathematically pairs those hashes together and hashes them again, repeatedly building a massive tree structure until it reaches a single, ultimate Root Hash.
  • The massive Hash Tree is physically appended to the very end of the system.img file.
  • The single Root Hash is stored securely inside the vbmeta partition.

At runtime, dm-verity only needs to initially know the Root Hash. When it reads a 4KB block, it pulls the corresponding branches from the Hash Tree at the end of the partition and mathematically traces them up to the Root Hash to verify total authenticity.

Handling dm-verity Errors

If dm-verity detects a corrupt block during a read operation, it immediately triggers a catastrophic failure known as EIO (Input/Output Error).

The kernel intentionally refuses to return the corrupt data to the app. Depending on the severity (and the OEM's specific security configuration), dm-verity will typically trigger an instant Kernel Panic, immediately rebooting the device to forcefully stop the compromised operating system from continuing to execute.

Previous Lesson
Android Verified Boot (AVB)
Course Complete!
You've finished all lessons.