Information Security 15 min read

Understanding dm-verity: Design Principles, Application Layer, and Kernel Implementation

dm‑verity is a Linux device‑mapper target that protects a data partition’s integrity by using a compile‑time hash‑tree stored on a separate hash device, with Android employing it for verified boot; user‑space creates the dm device, loads the verity table, activates it, while the kernel’s dev_create, table_load, and suspend handlers set up mapped_device structures and enforce per‑block hash verification during I/O.

OPPO Kernel Craftsman
OPPO Kernel Craftsman
OPPO Kernel Craftsman
Understanding dm-verity: Design Principles, Application Layer, and Kernel Implementation

dm-verity is a target device type in the device‑mapper framework that guarantees the integrity of a device or its partitions.

It relies on two underlying devices: a data device that stores the actual data and a hash device that stores hash values used to verify the data device.

The mapper device and the target device have a one‑to‑one relationship. Read operations on the mapper are forwarded to the target device, where dm‑verity maps them to reads on the data device and adds an extra hash verification step by comparing the computed hash with the value stored on the hash device.

Design principle (Android focus)

On Android, dm‑verity is used during image boot to verify system partitions (e.g., system , vendor ) and ensure they have not been tampered with. The verification is based on a hash‑tree (hashtree) built at compile time.

During compilation, each 4 KB block of the image is hashed, forming layer 0. The hashes of layer 0 are themselves hashed to form layer 1, and this process continues until a single 4 KB block containing the root hash is produced.

The root hash is signed and stored to protect the hash tree itself from tampering. At runtime, each accessed 4 KB block is hashed and compared with the corresponding hash in the tree; a mismatch indicates corruption or malicious modification.

For a 1 GB image, the process yields 262 144 data blocks, 2 048 blocks for layer 0 hashes, 16 blocks for layer 1, and finally one block for the root hash.

Using a hash tree dramatically reduces the number of hash calculations needed for verification: only one hash per tree level (e.g., three hashes for a three‑level tree) instead of a hash per data block.

Application‑layer workflow (three steps)

1. Create dm device

• Open the device‑mapper node: open /dev/device-mapper

• Pass the partition name and a generated UUID to the DM_DEV_CREATE ioctl.

2. Load verity table

The verity table contains fields such as:

Verity target version

Data block device

Hash block device

Data block size

Hash block size

Number of data blocks

Hash start block

Hash algorithm

Root digest (root hash)

Salt

The table is passed to the kernel via the DM_TABLE_LOAD ioctl.

3. Activate dm device

The DM_DEV_SUSPEND ioctl (without the DM_SUSPEND_FLAG ) activates the device, effectively resuming normal operation.

Overall, the application performs create → load verity table → activate dm device to set up real‑time block verification.

Kernel‑layer implementation (three steps)

1. dev_create – handles the DM_DEV_CREATE ioctl.

• Validates the partition name.

• Allocates and initializes a mapped‑device structure, assigns a minor number (e.g., dm‑1 ), registers a request queue with blk_queue_make_request , and registers the device with the kernel.

• Inserts the mapped device into a global hash table.

2. dm_ctl_ioctl(DM_TABLE_LOAD_CMD) – processes the DM_TABLE_LOAD ioctl.

• Parses the verity table, creates dm_table and dm_target structures, and invokes the target‑type constructor to build the target device.

3. dm_ctl_ioctl(DM_DEV_SUSPEND_CMD) – handles the DM_DEV_SUSPEND ioctl.

• Links the mapped device with its dm_table , completing the creation of a usable logical block device.

The key kernel structures involved are mapped_device , dm_table , dm_target , target_type , and the specific target device (dm‑verity).

Core data flow

After the application creates, loads, and activates the dm device, the logical block device is mounted. I/O requests from the filesystem are forwarded to the target device, where the hashtree is consulted to verify each block’s hash before the data is returned.

Conclusion

The article presents the design rationale of dm‑verity, demonstrates how the Android platform leverages it for verified boot, details the user‑space ioctl sequence, and explains the corresponding kernel implementation, culminating in a clear picture of the end‑to‑end integrity‑verification data flow.

AndroidLinux kerneldevice-mapperdm-verityhash treeintegrity verification
OPPO Kernel Craftsman
Written by

OPPO Kernel Craftsman

Sharing Linux kernel-related cutting-edge technology, technical articles, technical news, and curated tutorials

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.