MA-18087-1 Enhance virtual A/B slot check
authorJi Luo <ji.luo@nxp.com>
Wed, 21 Oct 2020 02:11:51 +0000 (10:11 +0800)
committerJi Luo <ji.luo@nxp.com>
Thu, 13 May 2021 01:49:18 +0000 (09:49 +0800)
Set the initial 'source_slot' in 'misc_virtual_ab_message' as
the current slot. At the same time, add slot checks before
erase data if virtual A/B is enabled.

Test: virtual A/B update and erase.

Signed-off-by: Ji Luo <ji.luo@nxp.com>
Change-Id: I84896335a95d9188b85e114037b470b3f4e7a209
(cherry picked from commit a522c2245c3e58adbbcb99c43e0917ce315cc1aa)
(cherry picked from commit 40a1e64ded230e1c2b3d76cccaea1f910ed0d6d6)

drivers/fastboot/fb_fsl/fb_fsl_command.c
drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.c
drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.h
lib/avb/fsl/fsl_bootctrl.c
lib/avb/fsl/fsl_bootctrl.h

index 4f648d5..f6f7eae 100644 (file)
@@ -413,7 +413,8 @@ static FbLockState do_fastboot_unlock(bool force)
 #endif
 
 #ifdef CONFIG_VIRTUAL_AB_SUPPORT
-               if (virtual_ab_update_is_merging() || virtual_ab_update_is_snapshoted()) {
+               if (virtual_ab_update_is_merging() ||
+                       (virtual_ab_update_is_snapshoted() && !virtual_ab_slot_match())) {
                        printf("Can not erase userdata while a snapshot update is in progress!\n");
                        return FASTBOOT_LOCK_ERROR;
                }
@@ -441,7 +442,8 @@ static FbLockState do_fastboot_lock(void)
        }
 
 #ifdef CONFIG_VIRTUAL_AB_SUPPORT
-               if (virtual_ab_update_is_merging() || virtual_ab_update_is_snapshoted()) {
+               if (virtual_ab_update_is_merging() ||
+                       (virtual_ab_update_is_snapshoted() && !virtual_ab_slot_match())) {
                        printf("Can not erase userdata while a snapshot update is in progress!\n");
                        return FASTBOOT_LOCK_ERROR;
                }
index 09e54f5..11260e6 100644 (file)
@@ -13,6 +13,7 @@
 static int read_virtual_ab_message(misc_virtual_ab_message *message)
 {
        size_t num_bytes;
+       int source_slot;
 
        if (fsl_read_from_partition_multi(NULL, FASTBOOT_PARTITION_MISC,
                                        SYSTEM_SPACE_SIZE_IN_MISC,
@@ -24,11 +25,18 @@ static int read_virtual_ab_message(misc_virtual_ab_message *message)
 
        if ((message->magic != MISC_VIRTUAL_AB_MAGIC_HEADER) ||
                (message->version != MISC_VIRTUAL_AB_MESSAGE_VERSION)) {
-               printf("Invalid virtual AB status, resetting...");
+               printf("Invalid virtual AB status, resetting...\n");
                message->version = MISC_VIRTUAL_AB_MESSAGE_VERSION;
                message->magic = MISC_VIRTUAL_AB_MAGIC_HEADER;
                message->merge_status = VIRTUAL_AB_NONE;
-               message->source_slot = 0;
+
+               /* Reset the source slot as the current slot */
+               source_slot = current_slot();
+               if (source_slot != -1)
+                       message->source_slot = source_slot;
+               else
+                       return -1;
+
                if (fsl_write_to_partition(NULL, FASTBOOT_PARTITION_MISC,
                                                SYSTEM_SPACE_SIZE_IN_MISC,
                                                sizeof(misc_virtual_ab_message),
@@ -49,7 +57,8 @@ bool partition_is_protected_during_merge(char *part)
        if ((!strncmp(part, "misc", sizeof("misc")) ||
                !strncmp(part, "userdata", sizeof("userdata")) ||
                !strncmp(part, "metadata", sizeof("metadata"))) &&
-               (virtual_ab_update_is_merging() || virtual_ab_update_is_snapshoted()))
+               (virtual_ab_update_is_merging() ||
+                (virtual_ab_update_is_snapshoted() && !virtual_ab_slot_match())))
                return true;
        else
                return false;
@@ -76,6 +85,17 @@ bool virtual_ab_update_is_snapshoted(void)
                return false;
 }
 
+bool virtual_ab_slot_match(void)
+{
+       misc_virtual_ab_message message;
+       read_virtual_ab_message(&message);
+
+       if (message.source_slot == current_slot())
+               return true;
+       else
+               return false;
+}
+
 int virtual_ab_cancel_update(void)
 {
        misc_virtual_ab_message message;
index 75ceb55..3b33cd7 100644 (file)
@@ -14,4 +14,5 @@ typedef enum {
 bool partition_is_protected_during_merge(char *part);
 bool virtual_ab_update_is_merging(void);
 bool virtual_ab_update_is_snapshoted(void);
+bool virtual_ab_slot_match(void);
 int virtual_ab_cancel_update(void);
index 0414f09..db96b74 100755 (executable)
@@ -37,6 +37,7 @@
  * hardware/interfaces/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
  */
 #define FSL_AB_METADATA_MISC_PARTITION_OFFSET 2048
+extern AvbABOps fsl_avb_ab_ops;
 
 static char *slot_suffix[AVB_AB_SLOT_NUM] = {"_a", "_b"};
 
@@ -61,6 +62,19 @@ int get_curr_slot(struct bootloader_control *ab_data) {
                return -1;
 }
 
+/* Return current slot without passing 'bootloader_control' struct */
+int current_slot(void) {
+       struct bootloader_control ab_data;
+
+       /* Load A/B metadata and decide which slot we are going to load */
+       if (fsl_avb_ab_ops.read_ab_metadata(&fsl_avb_ab_ops, &ab_data) !=
+                                           AVB_IO_RESULT_OK) {
+               printf("Error loading AB metadata from misc!\n");
+               return -1;
+       }
+       return get_curr_slot(&ab_data);
+}
+
 int slotidx_from_suffix(char *suffix) {
        int slot = -1;
 
@@ -1048,7 +1062,6 @@ out:
        return ret;
 }
 
-extern AvbABOps fsl_avb_ab_ops;
 static bool spl_recovery_flag = false;
 bool is_spl_recovery(void)
 {
index 2d5be97..6c7b307 100644 (file)
@@ -133,6 +133,13 @@ bool is_slotvar_avb(char *cmd);
  * */
 int get_curr_slot(struct bootloader_control* ab_data);
 
+/* Get current bootable slot without passing the "bootloader_control" struct.
+ * return 0 for the first slot
+ * return 1 for the second slot
+ * return -1 for not supported slot
+ * */
+int current_slot(void);
+
 /* return 0 for the first slot
  * return 1 for the second slot
  * return -1 for not supported slot