mirror of https://github.com/wolfSSL/wolfBoot.git
F-6878: delta: reject non-multiple SECTOR_SIZE/DELTA_BLOCK_SIZE at build
The per-sector fill loop in wolfBoot_delta_update() advances in DELTA_BLOCK_SIZE steps, so a WOLFBOOT_SECTOR_SIZE that is not a multiple of DELTA_BLOCK_SIZE writes past the one-sector SWAP partition and misaligns the resume path. Enforce the invariant with a #error and add a negative build test (unit-delta-sector-align.py). Verification: full unit suite 1096 checks, 0 failures; new test fails pre-fix (misaligned config built), passes post-fix (build rejected).pull/882/head
parent
6883532da8
commit
f598b3fd41
|
|
@ -623,6 +623,13 @@ static int RAMFUNCTION wolfBoot_swap_and_final_erase(int resume)
|
|||
# define DELTA_BLOCK_SIZE 1024
|
||||
#endif
|
||||
|
||||
/* The per-sector fill loop advances in DELTA_BLOCK_SIZE steps, so a
|
||||
* sector that is not a multiple of the block size would be written
|
||||
* past the one-sector SWAP partition and misalign the resume path. */
|
||||
#if (WOLFBOOT_SECTOR_SIZE % DELTA_BLOCK_SIZE) != 0
|
||||
#error "Delta update: WOLFBOOT_SECTOR_SIZE % DELTA_BLOCK_SIZE != 0"
|
||||
#endif
|
||||
|
||||
static inline uint32_t wb_delta_im2n(uint32_t val)
|
||||
{
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
|
|
|
|||
|
|
@ -221,6 +221,7 @@ run: $(TESTS)
|
|||
python3 unit-sign-delta-tlv.py || exit 1
|
||||
python3 unit-sign-delta-cert-inv-off.py || exit 1
|
||||
python3 unit-sign-delta-basehash-cleanup.py || exit 1
|
||||
python3 unit-delta-sector-align.py || exit 1
|
||||
python3 unit-sign-custom-tlv-le.py || exit 1
|
||||
python3 unit-sign-custom-tlv-large.py || exit 1
|
||||
python3 unit-sign-custom-tlv-pubkey-der.py || exit 1
|
||||
|
|
@ -264,6 +265,14 @@ unit-update-flash-delta:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST
|
|||
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT \
|
||||
-DDELTA_UPDATES -DDELTA_BLOCK_SIZE=512 -D__WOLFBOOT \
|
||||
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT -DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
|
||||
# Intentionally misaligned config: the mock WOLFBOOT_SECTOR_SIZE (0x400) is
|
||||
# not a multiple of DELTA_BLOCK_SIZE (1536). Must fail to build with the
|
||||
# delta alignment #error. Used by unit-delta-sector-align.py only, so it is
|
||||
# not part of $(TESTS).
|
||||
unit-update-flash-delta-misalign:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
|
||||
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT \
|
||||
-DDELTA_UPDATES -DDELTA_BLOCK_SIZE=1536 -D__WOLFBOOT \
|
||||
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT -DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
|
||||
unit-update-flash-self-update:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
|
||||
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT \
|
||||
-DRAM_CODE -DARCH_SIM -DUNIT_TEST_SELF_UPDATE_ONLY \
|
||||
|
|
@ -808,6 +817,10 @@ unit-update-flash-delta: ../../include/target.h unit-update-flash.c
|
|||
gcc -o $@ unit-update-flash.c ../../src/image.c ../../src/delta.c \
|
||||
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sha256.c $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
unit-update-flash-delta-misalign: ../../include/target.h unit-update-flash.c
|
||||
gcc -o $@ unit-update-flash.c ../../src/image.c ../../src/delta.c \
|
||||
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sha256.c $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
unit-update-flash-enc:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
|
||||
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT \
|
||||
-DPART_SWAP_EXT -DEXT_ENCRYPTED -DENCRYPT_WITH_CHACHA -DHAVE_CHACHA \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env python3
|
||||
# unit-delta-sector-align.py
|
||||
#
|
||||
# Build-time invariant for DELTA_UPDATES: the per-sector fill loop in
|
||||
# wolfBoot_delta_update() (src/update_flash.c) calls wb_patch() with
|
||||
# DELTA_BLOCK_SIZE chunks until WOLFBOOT_SECTOR_SIZE bytes are produced, so
|
||||
# the reconstructed image is only sector-aligned when WOLFBOOT_SECTOR_SIZE is
|
||||
# a multiple of DELTA_BLOCK_SIZE. A mismatched config used to compile fine
|
||||
# and corrupt the delta apply (write past the one-sector SWAP partition,
|
||||
# misaligned resume); the build now rejects it with an #error.
|
||||
#
|
||||
# This test builds the real update_flash.c (via unit-update-flash.c) with a
|
||||
# deliberately misaligned DELTA_BLOCK_SIZE and asserts the build fails with
|
||||
# the invariant message.
|
||||
#
|
||||
# Copyright (C) 2026 wolfSSL Inc.
|
||||
#
|
||||
# This file is part of wolfBoot.
|
||||
#
|
||||
# wolfBoot is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wolfBoot is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
MESSAGE = "WOLFBOOT_SECTOR_SIZE % DELTA_BLOCK_SIZE != 0"
|
||||
|
||||
|
||||
def main():
|
||||
# The misalign target is not in $(TESTS) and its rule does not track
|
||||
# src/update_flash.c (included via unit-update-flash.c), so drop any
|
||||
# stale artifact to force a real rebuild.
|
||||
try:
|
||||
os.remove("unit-update-flash-delta-misalign")
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
p = subprocess.run(["make", "unit-update-flash-delta-misalign"],
|
||||
capture_output=True, text=True)
|
||||
if p.returncode == 0:
|
||||
print("FAIL: misaligned DELTA_BLOCK_SIZE config built, "
|
||||
"expected the sector alignment #error")
|
||||
return 1
|
||||
if MESSAGE not in (p.stdout + p.stderr):
|
||||
print("FAIL: build failed for the wrong reason:\n")
|
||||
print(p.stderr[-2000:])
|
||||
return 1
|
||||
print("PASS: misaligned DELTA_BLOCK_SIZE rejected at build time")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Reference in New Issue