Commit 61d280b9 authored by Thomas Altenbach's avatar Thomas Altenbach Committed by David Brown
Browse files

boot: bootutil: Fix max image size computation for swap-move/swap-offset



When computing the maximum image size in bootutil_max_image_size for
swap-move or swap-offset strategy, the computation was using the size of
the flash area provided as argument and was not taking into account the
size of the padding sector. This was causing an incorrect size to be
returned in some cases, for example when the two slots have the same
size or when the slots haven't the same size but the routine is called
for the slot containing the padding sector.

For example, let's imagine swap-move is being used on a device having a
sector size S and two slots of N bytes. This is valid configuration and
the maximum image size is N - S - T, T being the size of the trailer
rounded up to the next multiple of S. When calling
bootutil_max_image_size with either the primary or secondary slot, the
size N - T is returned, which is incorrect.

This commit fixes the issue by computing always the maximum image using
the size of the slot containing the padding and substracting the size of
the padding and of the aligned trailer.

Signed-off-by: default avatarThomas Altenbach <thomas.altenbach@legrand.com>
parent 17b56a0a
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -477,18 +477,27 @@ uint32_t bootutil_max_image_size(struct boot_loader_state *state, const struct f

    return slot_trailer_off - trailer_padding;
#elif defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_OFFSET)
    (void) state;
    (void) fap;

    struct flash_sector sector;
    /* get the last sector offset */
    int rc = flash_area_get_sector(fap, boot_status_off(fap), &sector);
    if (rc) {
        BOOT_LOG_ERR("Unable to determine flash sector of the image trailer");
        return 0; /* Returning of zero here should cause any check which uses
                   * this value to fail.
                   */
    }
    return flash_sector_get_off(&sector);
    /* The slot whose size is used to compute the maximum image size must be the one containing the
     * padding required for the swap. */
#ifdef MCUBOOT_SWAP_USING_MOVE
    size_t slot = BOOT_PRIMARY_SLOT;
#else
    size_t slot = BOOT_SECONDARY_SLOT;
#endif

    const struct flash_area *fap_padded_slot = BOOT_IMG_AREA(state, slot);
    assert(fap_padded_slot != NULL);

    size_t trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
    size_t sector_sz = boot_img_sector_size(state, slot, 0);
    size_t padding_sz = sector_sz;

    /* The trailer size needs to be sector-aligned */
    trailer_sz = ALIGN_UP(trailer_sz, sector_sz);

    return flash_area_get_size(fap_padded_slot) - trailer_sz - padding_sz;
#elif defined(MCUBOOT_OVERWRITE_ONLY)
    (void) state;
    return boot_swap_info_off(fap);