Android - How to disable dm-verity on Android with "user" build type ROM?
I'm going to give a general overview of how dm-verity
and related things work on Android according to my limited knowledge. Situation might differ on different devices and ROMs.
HOW IS DM-VERITY ENFORCED?
dm-verity
(Verified Boot and AVB) as well as dm-crypt
(FDE) are targets of device-mapper
feature of Linux kernel. dm-verity
verifies the integrity of each block as they are read from block device; enforced by init_first_stage
as per fs_mgr_flags
set in fstab (1). On system-as-root devices (A/B
and non-A/B
), kernel is patched to force verity while mounting /system
and /vendor
if verify
/avb
flags are found in fstab device tree (dtb).
dm-crypt
decrypts/encrypts data transparently when read/written from/to block device. FBE is based on a different kernel framework fscrypt
; but both are managed by vold
(which runs as a native service) if fs_mgr_flags
contain voldmanaged
.
WHERE FSTAB IS?
fstab
has traditionally been a file on Linux to specify filesystems to be mounted on boot. It's a core component of fs_mgr
functionality on Android.
On pre-Oreo releases fstab
was in ramdisk
. With Treble it was moved to /vendor
(or /system/vendor
) while the fstab entries for system
and vendor
(and odm
) are moved to Device Tree Blob (dtb
). Kernel exports dtb fstab
entries in device tree directory at /proc/device-tree/firmware/android
.
Some OEMs also put fstab
in odm
or nvdata
partitions.
Source: Android Storage Device Configuration
WHERE DTB IS?
Device Tree is a data structure for describing hardware which is not discoverable to kernel. Device Tree Source (dts
) can be converted to dtb
(binary blob of DT) and vice versa using dtc
. DTB is loaded by bootloader at boot time and passed to kernel so that it can discover hardware and create device nodes accordingly.
DTB is either:
- Appended to kernel
zImage
orImage.gz
inboot.img
(2). It can be split fromgzip
archive usingsplit-appended-dtb (sadtb)
. Or in
dtbo
partition as some OEMs do. This can be checked with:~# ls -l /dev/block/bootdevice/by-name/dtbo* ~# grep -C5 PARTNAME=dtbo /sys/dev/block/*/uevent | grep DEVNAME | sed 's/.*=//; s|^|/dev/block/&|'
- Or at the end of
boot.img
after 2nd stage, or inodm
partition (rare, some OEMs do).
Also if the device is non-A/B
, dtb
(from boot.img
and/or dtbo
partition) is also added to recovery.img
in DTBO section after header, kernel, ramdisk and 2nd stage (3). However this doesn't matter for normal boot. But if the device is also system-as-root
, Magisk needs to be installed in this recovery partition as the boot.img
contains no ramdisk
(4).
In case if DTB is not appended to kernel, dtb(s)
are converted to dtb.img
using mkdtimg
. Same tool can dump back the image.
Source: Implementing DTO
HOW TO DISABLE DM-VERITY?
On userdebug
ROMs, dm-verity
can be disabled using adb
. It modifies magic number of verity metadata block (5, 6) which is written after the last filesystem block on block device (system
or vendor
) (7). Quoted from here:
the absence of this magic number will halt the verification process
In case of AVB, adb
modifies vbmeta header
to disable hashtree image verification (8, 9). Quoted from here:
if the
AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED
flag is set in the top-level vbmeta, thenandroidboot.veritymode
is set to disabled
On user
builds ro.debuggable
is 0
and adbd
isn't running as root. Also there are other differences like that of ALLOW_ADBD_DISABLE_VERITY
, so adb
won't disable dm-verity
. Other approach is to remove verify
or avb
(10) flag from fstab
. Quoted from here:
To verify the partition...
...
In the fstab for the relevant entry, addverify
to thefs_mgr
flags.
Similarly to remove encryption, forceencrypt=
, forcefdeorfbe=
or fileencryption=
need to be replaced with encryptable=
. However encryption cannot be removed without factory reset (FBE too?), so unchecking Preserve force encryption
in Magisk app will do nothing.
Some OEMs also use support_scfs
fs_mgr
flag and ro.config.dmverity=true
property on devices with dm-verity
enabled.
There are also some exploits discovered in bootloader and adb implementation of some OEMs which can be used to disable dm-verity
on affected devices. However such security flaws usually get fixed over time with updates from OEMs.
OPTION 1
Set options in configuration file before installing Magisk:
~# echo 'KEEPVERITY=false' >/cache/.magisk
~# echo 'KEEPFORCEENCRYPT=true' >>/cache/.magisk
If installed, after unchecking Preserve AVB v2.0/dm-verity
in app, Magisk needs to be reinstalled. Quoted from here:
in Magisk Manager, “Uninstall > Restore Images” to restore the images, check “Preserve AVB 2.0/dm-verity” box in Advanced Settings, then reinstall Magisk via the app.
OPTION 2
Use some dm-verity
disabler zips like this.
OPTION 3
Figure out where the fstab
entries of /system
and /vendor
are on your device.
If in ramdisk
(pre-Treble):
- Extract
ramdisk
, modifyfstab
and repack. Or patch
ramdisk
directly:~# magiskboot cpio ramdisk.cpio 'patch false true'
If in dtb
:
- If appended to kernel:
- Extract
boot.img
- Split appended
dtb(s)
- Patch
dtb(s)
. - Append
dtb(s)
to kernel - Repack
boot.img
- Extract
- If in
dtbo
partition or inboot.img
after 2nd stage, patchdtb.img
and write back to partition orboot.img
.
How to Unpack / Repack Boot or Recovery image and Ramdisk?
Use AIK or magiskboot
.
How to Patch dtb
?
Patch directly using magiskboot
or manually convert dtb
to dts
, edit dts
with any text editor to remove dm-verity
flags, and convert dts
back to dtb
.
RELATED:
- How Magisk works?
- Android Device Partitions and Filesystems