Skip to content

Commit

Permalink
boot: bootutil: Fix invalid last sector computation for swap-scratch
Browse files Browse the repository at this point in the history
At the beginning of a swap-scratch upgrade, the index of the last sector
in the primary slot that need to be swapped is computed using the
'find_last_sector_idx' routine. However, if the primary slot is composed
of larger sectors than the secondary slots, this routine could return a
wrong sector index for the primary slot. The index might even be outside
the primary slot, which would lead to (at best) a simple failure of the
upgrade and at worst a corruption of the flash memory bricking the
device.

This commit fixes the issue by ensuring 'find_last_sector_idx' always
returns a valid sector index for the primary slot.

Signed-off-by: Thomas Altenbach <[email protected]>
  • Loading branch information
taltenbach authored and nordicjm committed Mar 5, 2025
1 parent 7724bcf commit fbd2267
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions boot/bootutil/src/swap_scratch.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,13 +464,15 @@ boot_copy_sz(const struct boot_loader_state *state, int last_sector_idx,
static int
find_last_sector_idx(const struct boot_loader_state *state, uint32_t copy_size)
{
int last_sector_idx;
int last_sector_idx_primary;
int last_sector_idx_secondary;
uint32_t primary_slot_size;
uint32_t secondary_slot_size;

primary_slot_size = 0;
secondary_slot_size = 0;
last_sector_idx = 0;
last_sector_idx_primary = 0;
last_sector_idx_secondary = 0;

/*
* Knowing the size of the largest image between both slots, here we
Expand All @@ -483,23 +485,24 @@ find_last_sector_idx(const struct boot_loader_state *state, uint32_t copy_size)
(primary_slot_size < secondary_slot_size)) {
primary_slot_size += boot_img_sector_size(state,
BOOT_PRIMARY_SLOT,
last_sector_idx);
last_sector_idx_primary);
++last_sector_idx_primary;
}
if ((secondary_slot_size < copy_size) ||
(secondary_slot_size < primary_slot_size)) {
secondary_slot_size += boot_img_sector_size(state,
BOOT_SECONDARY_SLOT,
last_sector_idx);
last_sector_idx_secondary);
++last_sector_idx_secondary;
}
if (primary_slot_size >= copy_size &&
secondary_slot_size >= copy_size &&
primary_slot_size == secondary_slot_size) {
break;
}
last_sector_idx++;
}

return last_sector_idx;
return last_sector_idx_primary - 1;
}

/**
Expand Down

0 comments on commit fbd2267

Please sign in to comment.