]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
bootstd: android: Allow boot with AVB failures when unlocked
authorMattijs Korpershoek <mkorpershoek@baylibre.com>
Wed, 8 Jan 2025 14:38:42 +0000 (15:38 +0100)
committerMattijs Korpershoek <mkorpershoek@baylibre.com>
Thu, 23 Jan 2025 14:23:05 +0000 (15:23 +0100)
When the bootloader is UNLOCKED, it should be possible to boot Android
even if AVB reports verification errors [1].

This allows developers to flash modified partitions on
userdebug/engineering builds.

Developers can do so on unlocked devices with:
$ fastboot flash --disable-verity --disable-verification vbmeta vbmeta.img

In such case, bootmeth_android refuses to boot.

Allow the boot to continue when the device is UNLOCKED and AVB reports
verification errors.

[1] https://source.android.com/docs/security/features/verifiedboot/boot-flow#unlocked-devices

Fixes: 125d9f3306ea ("bootstd: Add a bootmeth for Android")
Reviewed-by: Julien Masson <jmasson@baylibre.com>
Link: https://lore.kernel.org/r/20250108-avb-disable-verif-v2-2-ba7d3b0d5b6a@baylibre.com
Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
boot/bootmeth_android.c

index 4ce89d5bcefb9b3dd973fd409c90ef4ea61c2ae1..a5a86b29d7f02ec5be7989af251153cecf29b489 100644 (file)
@@ -450,17 +450,26 @@ static int run_avb_verification(struct bootflow *bflow)
                                 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
                                 &out_data);
 
-       if (result != AVB_SLOT_VERIFY_RESULT_OK) {
-               printf("Verification failed, reason: %s\n",
-                      str_avb_slot_error(result));
-               avb_slot_verify_data_free(out_data);
-               return log_msg_ret("avb verify", -EIO);
-       }
-
-       if (unlocked)
-               boot_state = AVB_ORANGE;
-       else
+       if (!unlocked) {
+               /* When device is locked, we only accept AVB_SLOT_VERIFY_RESULT_OK */
+               if (result != AVB_SLOT_VERIFY_RESULT_OK) {
+                       printf("Verification failed, reason: %s\n",
+                              str_avb_slot_error(result));
+                       avb_slot_verify_data_free(out_data);
+                       return log_msg_ret("avb verify", -EIO);
+               }
                boot_state = AVB_GREEN;
+       } else {
+               /* When device is unlocked, we also accept verification errors */
+               if (result != AVB_SLOT_VERIFY_RESULT_OK &&
+                   result != AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION) {
+                       printf("Unlocked verification failed, reason: %s\n",
+                              str_avb_slot_error(result));
+                       avb_slot_verify_data_free(out_data);
+                       return log_msg_ret("avb verify unlocked", -EIO);
+               }
+               boot_state = AVB_ORANGE;
+       }
 
        extra_args = avb_set_state(avb_ops, boot_state);
        if (extra_args) {
@@ -470,9 +479,11 @@ static int run_avb_verification(struct bootflow *bflow)
                        goto free_out_data;
        }
 
-       ret = avb_append_commandline(bflow, out_data->cmdline);
-       if (ret < 0)
-               goto free_out_data;
+       if (result == AVB_SLOT_VERIFY_RESULT_OK) {
+               ret = avb_append_commandline(bflow, out_data->cmdline);
+               if (ret < 0)
+                       goto free_out_data;
+       }
 
        return 0;