boot: replace boot_is_version_sufficient() function
Replace the boot_is_version_sufficient() function with a new,
boot_version_cmp() function which is more straightforward and
distinguishes the 3 possible results of the comparison.
Update the error handling accordingly.
Change-Id: Ie7d4f892dc3df2c6ef82769c4d0676965b75b7b8
Signed-off-by: David Vincze <david.vincze@linaro.org>
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index 1094ff2..60815df 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -519,33 +519,39 @@
#if (BOOT_IMAGE_NUMBER > 1) || \
(defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION))
/**
- * Check if the version of the image is not older than required.
+ * Compare image version numbers not including the build number
*
- * @param req Required minimal image version.
- * @param ver Version of the image to be checked.
+ * @param ver1 Pointer to the first image version to compare.
+ * @param ver2 Pointer to the second image version to compare.
*
- * @return 0 if the version is sufficient, nonzero otherwise.
+ * @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.
*/
static int
-boot_is_version_sufficient(struct image_version *req,
- struct image_version *ver)
+boot_version_cmp(const struct image_version *ver1,
+ const struct image_version *ver2)
{
- if (ver->iv_major > req->iv_major) {
- return 0;
+ if (ver1->iv_major > ver2->iv_major) {
+ return 1;
}
- if (ver->iv_major < req->iv_major) {
- return BOOT_EBADVERSION;
+ if (ver1->iv_major < ver2->iv_major) {
+ return -1;
}
- /* The major version numbers are equal. */
- if (ver->iv_minor > req->iv_minor) {
- return 0;
+ /* The major version numbers are equal, continue comparison. */
+ if (ver1->iv_minor > ver2->iv_minor) {
+ return 1;
}
- if (ver->iv_minor < req->iv_minor) {
- return BOOT_EBADVERSION;
+ if (ver1->iv_minor < ver2->iv_minor) {
+ return -1;
}
- /* The minor version numbers are equal. */
- if (ver->iv_revision < req->iv_revision) {
- return BOOT_EBADVERSION;
+ /* 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;
@@ -603,10 +609,10 @@
#if defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION)
if (slot != BOOT_PRIMARY_SLOT) {
/* Check if version of secondary slot is sufficient */
- rc = boot_is_version_sufficient(
- &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver,
- &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver);
- if (rc != 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) {
+ rc = boot_version_cmp(
+ &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver,
+ &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver);
+ if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) {
BOOT_LOG_ERR("insufficient version in secondary slot");
flash_area_erase(fap, 0, fap->fa_size);
/* Image in the secondary slot does not satisfy version requirement.
@@ -1126,8 +1132,8 @@
: BOOT_PRIMARY_SLOT;
dep_version = &state->imgs[dep->image_id][dep_slot].hdr.ih_ver;
- rc = boot_is_version_sufficient(&dep->image_min_version, dep_version);
- if (rc != 0) {
+ rc = boot_version_cmp(dep_version, &dep->image_min_version);
+ if (rc < 0) {
/* Dependency not satisfied.
* Modify the swap type to decrease the version number of the image
* (which will be located in the primary slot after the boot process),
@@ -1145,6 +1151,9 @@
default:
break;
}
+ } else {
+ /* Dependency satisfied. */
+ rc = 0;
}
return rc;
@@ -1243,7 +1252,7 @@
if (rc == 0) {
/* All dependencies've been satisfied, continue with next image. */
BOOT_CURR_IMG(state)++;
- } else if (rc == BOOT_EBADVERSION) {
+ } else {
/* Cannot upgrade due to non-met dependencies, so disable all
* image upgrades.
*/
@@ -1252,9 +1261,6 @@
BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
}
break;
- } else {
- /* Other error happened, images are inconsistent */
- return rc;
}
}
return rc;
@@ -1675,7 +1681,7 @@
* are all satisfied and update swap type if necessary.
*/
rc = boot_verify_dependencies(state);
- if (rc == BOOT_EBADVERSION) {
+ if (rc != 0) {
/*
* It was impossible to upgrade because the expected dependency version
* was not available. Here we already changed the swap_type so that