Android system dm-verity 优化和实战

        Android O/P 版本以来,谷歌加入了system-as-root的特性,此时ramdisk和system是一起放在同一个system.img镜像中的。而系统起来之后也就不存在system分区了,而是直接把system镜像挂载到/根目录上。那么这个操作是怎么进行的呢?
system.img默认是需要使能dm-verity来挂载的,那么这就涉及到如何使能dm-verity来挂载/根分区。还有一个重要的点,如果我们想要禁用dm-verity功能又要如何操作,这又涉及更深的层次,如果可配置/根分区的挂载方式为dm-verity或者非dm-verity方式

        根目录的挂载必须要由kernel去完成了。因为根目录挂载是先于init的运行的,没有根目录就不会有init。那么如何由kernel去挂载system.img镜像呢?

        由此我们就通过传入不同的cmdline的方式来启动kernel,进而挂载根目录,也就是system.img镜像。

        Kernel command line: console=tty0 console=ttyS0,921600n1 vmalloc=496M slub_max_order=0 slub_debug=OFZPU androidboot.hardware=mt6771 firmware_class.path=/vendor/firmware loop.max_part=7 has_battery_removed=0 maxcpus=8 androidboot.verifiedbootstate=green skip_initramfs rootwait ro init=/init root=/dev/dm-0 dm="system none ro,0 1 android-verity PARTUUID=a4da8f1b-fe07-433b-95cb-84a5f23e477b " androidboot.veritymode=enforcing bootopt=64S3,32N2,64N2 buildvariant=user veritykeyid=id:e58276dac7669ff2e60185d6763d16bf6d898136 androidboot.atm=disabled androidboot.meta_log_disable=0 androidboot.dtbo_idx=0 lpddr_used_index=0 

1、   分别查找内核代码关键字:

                dm=        veritykeyid=
[    2.883032] <7>.(4)[1:swapper/0]device-mapper: init: attempting early device configuration.
[    2.883764] <7>.(5)[1:swapper/0]device-mapper: init: adding target '0 1 android-verity PARTUUID=a4da8f1b-fe07-433b-95cb-84a5f23e477b '

[    2.883783] <7>.(5)[1:swapper/0]device-mapper: android-verity: key:id:7e4333f9bba00adfe0ede979e28ed1920492b40f dev:PARTUUID=a4da8f1b-fe07-433b-95cb-84a5f23e477b
[    2.893211] <7>.(0)[1:swapper/0]device-mapper: android-verity: bio magic_number:2952900609 protocol_version:0 table_length:254

[    2.893223] <7>.(0)[1:swapper/0]device-mapper: android-verity: verity_table: 1 /dev/block/platform/bootdevice/by-name/system /dev/block/platform/bootdevice/by-name/system 4096 4096 903183 903183 sha256 01d43da3f751712bd6c7a105a2a65e9cc6575b5658e1d00fea90b8c83c5257f3 aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7

[    2.894313] <7>.(0)[1:swapper/0]device-mapper: android-verity: Signature verification success
[    2.894327] <7>.(0)[1:swapper/0]device-mapper: android-verity: Data sectors 7225464

[    2.895497] <7>.(5)[1:swapper/0]device-mapper: android-verity: android-verity mounted as verity target
[    2.895650] <7>.(4)[1:swapper/0]device-mapper: init: dm-0 is ready

   kernel-4.4\drivers\md\dm-android-verity.c  

       __setup("veritykeyid=", verity_keyid_param);

   kernel-4.4\init\do_mounts_dm.c

        __setup("dm=", dm_setup);

      static int __init dm_setup(char *str)

 

2、   verity pub key

        kernel-4.4/certs$ ls
            Kconfig  ko_test_prvk.pem

           Makefile   system_keyring.c

          system_certificates.S    verity.x509.pem

         这里将Puk 编译进内核,并挂载在 /目录下, 但system验签时,使用的是代码段里的。

         key_ref = keyring_search(make_key_ref(system_trusted_keyring, 1),
        &key_type_asymmetric, key_id);

        key = key_ref_to_ptr(key_ref);

 

3、   veritykeyid=  来源

    build/make/tools/releasetools/sign_target_files_apks.py

    # Extract keyid using openssl command.
    p = common.Run(["openssl", "x509", "-in", key_path, "-text"],
                   stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    keyid, stderr = p.communicate()

    keyid = re.search(
        r'keyid:([0-9a-fA-F:]*)', keyid).group(1).replace(':', '').lower()
    print("Replacing verity keyid with {}".format(keyid))

  common.ZipWriteStr(output_zip, "BOOT/cmdline", out_cmdline)

 编译log(可手动敲下命令):veritykeyid=id:\`openssl x509 -in build/target/product/security/verity.x509.pem -text | grep keyid 

   X509v3 Authority Key Identifier: 
                keyid:7E:43:33:F9:BB:A0:0A:DF:E0:ED:E9:79:E2:8E:D1:92:04:92:B4:0F

  4、下一篇,补充 system 到底是如何去dm验证的。

你可能感兴趣的:(Android system dm-verity 优化和实战)