ext: lib: mcumgr: Fix slot-1 image upload deadlock condition
If a firmware update is attempted with a corrupt image and a power outage or reset occurs while the bootloader (mcubooot v3.1 in this case) is erasing the corrupt image then slot-1 can be left in a state where mcuboot has not properly released slot-1 and a DFU transfer can no longer happen. Attempts to upload will transfer 0 bytes as the trailer at the end of the slot remains present and indicates the slot is 'in use' blocking the slot erase operation on reception of the 1st image block or a image erase command. This commit fixes this issue by adding a addition requirement that a slot is 'in use'. The additional requirement is that the image header magic value located at the beginning of the slot is also present. If this additional requirement is not also met then the slot is considered not 'in use'. Signed-off-by: Nick Ward <nick.ward@setec.com.au>
This commit is contained in:
parent
17e2618f2f
commit
4c1c1732ed
|
@ -237,8 +237,14 @@ img_mgmt_erase(struct mgmt_ctxt *ctxt)
|
|||
{
|
||||
CborError err;
|
||||
int rc;
|
||||
bool slot1_in_use;
|
||||
|
||||
if (img_mgmt_slot_in_use(1)) {
|
||||
rc = img_mgmt_slot_in_use(1, &slot1_in_use);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (slot1_in_use) {
|
||||
/* No free slot. */
|
||||
return MGMT_ERR_EBADSTATE;
|
||||
}
|
||||
|
@ -307,8 +313,14 @@ img_mgmt_upload_first_chunk(struct mgmt_ctxt *ctxt, const uint8_t *req_data,
|
|||
size_t data_sha_len)
|
||||
{
|
||||
int rc;
|
||||
bool slot1_in_use;
|
||||
|
||||
if (img_mgmt_slot_in_use(1)) {
|
||||
rc = img_mgmt_slot_in_use(1, &slot1_in_use);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (slot1_in_use) {
|
||||
/* No free slot. */
|
||||
return MGMT_ERR_ENOMEM;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ int img_mgmt_find_by_hash(uint8_t *find, struct image_version *ver);
|
|||
int img_mgmt_find_by_ver(struct image_version *find, uint8_t *hash);
|
||||
int img_mgmt_read_info(int image_slot, struct image_version *ver,
|
||||
uint8_t *hash, uint32_t *flags);
|
||||
int img_mgmt_slot_in_use(int slot);
|
||||
int img_mgmt_slot_in_use(int slot, bool *in_use);
|
||||
int img_mgmt_state_read(struct mgmt_ctxt *ctxt);
|
||||
int img_mgmt_state_write(struct mgmt_ctxt *njb);
|
||||
int img_mgmt_ver_str(const struct image_version *ver, char *dst);
|
||||
|
|
|
@ -108,14 +108,28 @@ img_mgmt_state_any_pending(void)
|
|||
* the slot can be freely erased.
|
||||
*/
|
||||
int
|
||||
img_mgmt_slot_in_use(int slot)
|
||||
img_mgmt_slot_in_use(int slot, bool *in_use)
|
||||
{
|
||||
uint8_t state_flags;
|
||||
struct image_header hdr;
|
||||
int rc;
|
||||
|
||||
state_flags = img_mgmt_state_flags(slot);
|
||||
return state_flags & IMG_MGMT_STATE_F_ACTIVE ||
|
||||
state_flags & IMG_MGMT_STATE_F_CONFIRMED ||
|
||||
state_flags & IMG_MGMT_STATE_F_PENDING;
|
||||
*in_use = state_flags & IMG_MGMT_STATE_F_ACTIVE ||
|
||||
state_flags & IMG_MGMT_STATE_F_CONFIRMED ||
|
||||
state_flags & IMG_MGMT_STATE_F_PENDING;
|
||||
|
||||
/* Check validity of in_use state by checking the image header contains
|
||||
* the magic value.
|
||||
*/
|
||||
rc = img_mgmt_impl_read(slot, 0, &hdr, sizeof hdr);
|
||||
|
||||
if (hdr.ih_magic != IMAGE_MAGIC) {
|
||||
/* Image is invalid */
|
||||
*in_use = false;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue