How to disable dm-verity on Android with "user" build type ROM?


Question

I have One Plus 6T Android device which has a ROM of build type user. This device is rooted with Magisk and I want to disable dm-verity on this device. I have tried to run adb disable-verity but I got an error saying verity cannot be disabled/enabled - USER build



Is there any way to disable this?



Goal: Want to place customized sepolicy file under system_root directory. I have tried to do it with following commands:



C:\Users\GPU-Test>adb shell
OnePlus6T:/ $ su
OnePlus6T:/ # mount -o rw,remount /system_root
OnePlus6T:/ # cp /sdcard/selinux_policy_modified /system_root/sepolicy
cp: /system_root/sepolicy: Permission denied
1|OnePlus6T:/ # cp -f /sdcard/selinux_policy_modified /system_root/sepolicy
cp: /system_root/sepolicy: No such file or directory
1|OnePlus6T:/ # ^C
130|OnePlus6T:/ # exit
130|OnePlus6T:/ $ exit

C:\Users\GPU-Test>adb disable-verity
verity cannot be disabled/enabled - USER build



Also tried to disable Preserve force encryption and Preserve AVB 2.0/dm-verity checkbox but still the above commands have same result. Also on reboot these check-boxes enables again automatically.


Answer

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 or Image.gz in boot.img (2). It can be split from gzip archive using split-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 in odm 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, then androidboot.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, add verify to the fs_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, modify fstab 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


  • If in dtbo partition or in boot.img after 2nd stage, patch dtb.img and write back to partition or boot.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:




Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes