Skip to content

Commit

Permalink
boot_serial: Software downgrade prevention in serial recovery configu…
Browse files Browse the repository at this point in the history
…ration

Signed-off-by: mateo-ligne-netatmo <[email protected]>
  • Loading branch information
mateo-ligne-netatmo committed Dec 16, 2021
1 parent a59fef4 commit 61f392a
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 3 deletions.
41 changes: 41 additions & 0 deletions boot/boot_serial/src/boot_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
#include "bootutil_priv.h"
#endif

#ifdef MCUBOOT_DOWNGRADE_PREVENTION
#include "single_loader.h"
#endif

#include "serial_recovery_cbor.h"
#include "bootutil/boot_hooks.h"

Expand Down Expand Up @@ -102,6 +106,9 @@ static cbor_state_backups_t dummy_backups;
static cbor_state_t cbor_state = {
.backups = &dummy_backups
};
#ifdef MCUBOOT_DOWNGRADE_PREVENTION
static bool updatable;
#endif /*MCUBOOT_DOWNGRADE_PREVENTION*/

/**
* Function that processes MGMT_GROUP_ID_PERUSER mcumgr group and may be
Expand Down Expand Up @@ -255,6 +262,10 @@ bs_upload(char *buf, int len)
static off_t off_last = -1;
struct flash_sector sector;
#endif
#ifdef MCUBOOT_DOWNGRADE_PREVENTION
struct image_header* inc_hdr = NULL;
struct image_header st_hdr;
#endif /*MCUBOOT_DOWNGRADE_PREVENTION*/

img_num = 0;

Expand Down Expand Up @@ -317,6 +328,36 @@ bs_upload(char *buf, int len)
goto out;
}

#ifdef MCUBOOT_DOWNGRADE_PREVENTION
/* Comparison should happen once, on the reception of header */
if (off == 0)
{
inc_hdr = (struct image_header*)img_data;
rc = BOOT_HOOK_CALL(boot_read_image_header_hook,
BOOT_HOOK_REGULAR, 0, 0, &st_hdr);
if (rc == BOOT_HOOK_REGULAR)
{
flash_area_read(fap, 0, &st_hdr, sizeof(st_hdr));
}
updatable = true;
/* Check if a firmware is already stored, if yes, compare versions */
if (st_hdr.ih_img_size < flash_area_get_size(fap))
{
rc = boot_version_cmp(&st_hdr.ih_ver,
&inc_hdr->ih_ver);
if (rc > 0) {
BOOT_LOG_INF("Update aborted due to strictly lower firmware version");
updatable = false;
}
}
}
if (!updatable)
{
rc = MGMT_ERR_REJECTED_UPD;
goto out;
}
#endif /*MCUBOOT_DOWNGRADE_PREVENTION*/

if (off == 0) {
curr_off = 0;
if (data_len > flash_area_get_size(fap)) {
Expand Down
1 change: 1 addition & 0 deletions boot/boot_serial/src/boot_serial_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ extern "C" {
#define MGMT_ERR_EUNKNOWN 2
#define MGMT_ERR_EINVAL 3
#define MGMT_ERR_ENOTSUP 8
#define MGMT_ERR_REJECTED_UPD 10

#define NMGR_OP_READ 0
#define NMGR_OP_WRITE 2
Expand Down
2 changes: 1 addition & 1 deletion boot/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ choice

config MCUBOOT_DOWNGRADE_PREVENTION
bool "SW based downgrade prevention"
depends on BOOT_UPGRADE_ONLY
depends on BOOT_UPGRADE_ONLY || MCUBOOT_SERIAL
help
Prevent downgrades by enforcing incrementing version numbers.
When this option is set, any upgrade must have greater major version
Expand Down
16 changes: 16 additions & 0 deletions boot/zephyr/include/single_loader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2021-2021 Crodeon Technologies
*
*/

#ifndef H_SINGLE_LOADER_
#define H_SINGLE_LOADER_

int boot_image_load_header(const struct flash_area *fa_p,
struct image_header *hdr);

int boot_version_cmp(const struct image_version *ver1,
const struct image_version *ver2);
#endif
43 changes: 41 additions & 2 deletions boot/zephyr/single_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ boot_image_validate(const struct flash_area *fa_p,
}
#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */


/**
* Attempts to load image header from flash; verifies flash header fields.
*
Expand All @@ -57,7 +56,7 @@ boot_image_validate(const struct flash_area *fa_p,
*
* @return 0 on success, error code otherwise
*/
static int
int
boot_image_load_header(const struct flash_area *fa_p,
struct image_header *hdr)
{
Expand Down Expand Up @@ -90,6 +89,46 @@ boot_image_load_header(const struct flash_area *fa_p,
return 0;
}

#ifdef MCUBOOT_DOWNGRADE_PREVENTION
/**
* Compare image version numbers not including the build number
*
* @param ver1 Pointer to the first image version to compare.
* @param ver2 Pointer to the second image version to compare.
*
* @retval -1 If ver1 is strictly less than ver2.
* @retval 0 If the image version numbers are equal,
* (not including the build number).
* @retval 1 If ver1 is strictly greater than ver2.
*/
int
boot_version_cmp(const struct image_version *ver1,
const struct image_version *ver2)
{
if (ver1->iv_major > ver2->iv_major) {
return 1;
}
if (ver1->iv_major < ver2->iv_major) {
return -1;
}
/* The major version numbers are equal, continue comparison. */
if (ver1->iv_minor > ver2->iv_minor) {
return 1;
}
if (ver1->iv_minor < ver2->iv_minor) {
return -1;
}
/* The minor version numbers are equal, continue comparison. */
if (ver1->iv_revision > ver2->iv_revision) {
return 1;
}
if (ver1->iv_revision < ver2->iv_revision) {
return -1;
}

return 0;
}
#endif /*MCUBOOT_DOWNGRADE_PREVENTION*/

/**
* Gather information on image and prepare for booting.
Expand Down

0 comments on commit 61f392a

Please sign in to comment.