Commit bc18d7da authored by Jamie McCrae's avatar Jamie McCrae Committed by Jamie
Browse files

boot: boot_serial: Fix issue with CBOR and setting image state



Fixes an issue whereby when canonical mode for ZCBOR was enabled,
the state variables were not increased to handle the backup
states, and a bug whereby only secondary slots were checked for
status when setting image state, whilst generally this is the
intended outcome, a user should also be able to mark a primary
image as confirmed too for other modes such as direct-xip

Signed-off-by: default avatarJamie McCrae <jamie.mccrae@nordicsemi.no>
parent 81315483
Loading
Loading
Loading
Loading
+86 −67
Original line number Diff line number Diff line
@@ -177,11 +177,18 @@ static int boot_serial_get_hash(const struct image_header *hdr,
#endif
#endif

static zcbor_state_t cbor_state[2];
#ifdef ZCBOR_CANONICAL
/* Allow 3 extra states for backup states for all commands */
#define CBOR_EXTRA_STATES 3
#else
#define CBOR_EXTRA_STATES 0
#endif

static zcbor_state_t cbor_state[2 + CBOR_EXTRA_STATES];

void reset_cbor_state(void)
{
    zcbor_new_encode_state(cbor_state, 2, (uint8_t *)bs_obuf,
    zcbor_new_encode_state(cbor_state, ARRAY_SIZE(cbor_state), (uint8_t *)bs_obuf,
                           sizeof(bs_obuf), 0);
}

@@ -497,6 +504,7 @@ bs_set(char *buf, int len)
     *   "hash":<hash of image (OPTIONAL for single image only)>
     * }
     */
    uint32_t slot;
    uint8_t image_index = 0;
    size_t decoded = 0;
    uint8_t hash[IMAGE_HASH_SIZE];
@@ -509,8 +517,8 @@ bs_set(char *buf, int len)
    bool found = false;
#endif

    zcbor_state_t zsd[4];
    zcbor_new_state(zsd, sizeof(zsd) / sizeof(zcbor_state_t), (uint8_t *)buf, len, 1, NULL, 0);
    zcbor_state_t zsd[4 + CBOR_EXTRA_STATES];
    zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), (uint8_t *)buf, len, 1, NULL, 0);

    struct zcbor_map_decode_key_val image_set_state_decode[] = {
        ZCBOR_MAP_DECODE_KEY_DECODER("confirm", zcbor_bool_decode, &confirm),
@@ -536,7 +544,12 @@ bs_set(char *buf, int len)
    }

    if (img_hash.len != 0) {
        for (image_index = 0; image_index < BOOT_IMAGE_NUMBER; ++image_index) {
        IMAGES_ITER(image_index) {
#ifdef MCUBOOT_SWAP_USING_OFFSET
            int swap_status = boot_swap_type_multi(image_index);
#endif

            for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
                struct image_header hdr;
                uint32_t area_id;
                const struct flash_area *fap;
@@ -548,13 +561,14 @@ bs_set(char *buf, int len)
                uint32_t start_off = 0;
#endif

            area_id = flash_area_id_from_multi_image_slot(image_index, 1);
                area_id = flash_area_id_from_multi_image_slot(image_index, slot);
                if (flash_area_open(area_id, &fap)) {
                    BOOT_LOG_ERR("Failed to open flash area ID %d", area_id);
                    continue;
                }

#ifdef MCUBOOT_SWAP_USING_OFFSET
                if (slot == BOOT_SECONDARY_SLOT && swap_status != BOOT_SWAP_TYPE_REVERT) {
                    rc = flash_area_sectors(fap, &num_sectors, &sector_data);

                    if ((rc != 0 && rc != -ENOMEM) ||
@@ -564,6 +578,7 @@ bs_set(char *buf, int len)
                    }

                    start_off = sector_data.fs_size;
                }
#endif

                rc = BOOT_HOOK_CALL(boot_read_image_header_hook,
@@ -627,7 +642,8 @@ bs_set(char *buf, int len)
                if (rc == 0 && memcmp(hash, img_hash.value, sizeof(hash)) == 0) {
                    /* Hash matches, set this slot for test or confirmation */
                    found = true;
                break;
                    goto set_image_state;
                }
            }
        }

@@ -640,6 +656,7 @@ bs_set(char *buf, int len)
    }
#endif

set_image_state:
    rc = boot_set_pending_multi(image_index, confirm);

out:
@@ -683,6 +700,8 @@ bs_list_set(uint8_t op, char *buf, int len)
        bs_rc_rsp(MGMT_ERR_ENOTSUP);
#endif
    }

    reset_cbor_state();
}

#ifdef MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO
@@ -901,8 +920,8 @@ bs_upload(char *buf, int len)
    static uint32_t start_off = 0;
#endif

    zcbor_state_t zsd[4];
    zcbor_new_state(zsd, sizeof(zsd) / sizeof(zcbor_state_t), (uint8_t *)buf, len, 1, NULL, 0);
    zcbor_state_t zsd[4 + CBOR_EXTRA_STATES];
    zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), (uint8_t *)buf, len, 1, NULL, 0);

    struct zcbor_map_decode_key_val image_upload_decode[] = {
        ZCBOR_MAP_DECODE_KEY_DECODER("image", zcbor_uint32_decode, &img_num_tmp),
@@ -1210,8 +1229,8 @@ bs_echo(char *buf, int len)
    bool ok;
    uint32_t rc = MGMT_ERR_EINVAL;

    zcbor_state_t zsd[4];
    zcbor_new_state(zsd, sizeof(zsd) / sizeof(zcbor_state_t), (uint8_t *)buf, len, 1, NULL, 0);
    zcbor_state_t zsd[4 + CBOR_EXTRA_STATES];
    zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), (uint8_t *)buf, len, 1, NULL, 0);

    if (!zcbor_map_start_decode(zsd)) {
        goto out;