Skip to content

Commit e10d9c1

Browse files
committed
Fix RAM fallback partition reselection
F/2567
1 parent 00892c2 commit e10d9c1

3 files changed

Lines changed: 264 additions & 2 deletions

File tree

src/update_ram.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,12 @@ void RAMFUNCTION wolfBoot_start(void)
150150
else
151151
source_address = (uint32_t*)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
152152
#else
153-
active = wolfBoot_dualboot_candidate_addr((void**)&source_address);
153+
if (active < 0)
154+
active = wolfBoot_dualboot_candidate_addr((void**)&source_address);
155+
else if (active == PART_BOOT)
156+
source_address = (uint32_t*)hal_get_primary_address();
157+
else
158+
source_address = (uint32_t*)hal_get_update_address();
154159
#endif
155160
if (active < 0) { /* panic if no images available */
156161
wolfBoot_printf("No valid image found!\n");

tools/unit-tests/Makefile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ TESTS:=unit-parser unit-fdt unit-extflash unit-string unit-spi-flash unit-aes128
4848
unit-image unit-image-rsa unit-nvm unit-nvm-flagshome unit-enc-nvm \
4949
unit-enc-nvm-flagshome unit-delta unit-update-flash unit-update-flash-delta \
5050
unit-update-flash-self-update \
51-
unit-update-flash-enc unit-update-ram unit-pkcs11_store unit-psa_store unit-disk \
51+
unit-update-flash-enc unit-update-ram unit-update-ram-nofixed unit-pkcs11_store unit-psa_store unit-disk \
5252
unit-update-disk unit-multiboot unit-boot-x86-fsp unit-qspi-flash unit-tpm-rsa-exp \
5353
unit-image-nopart unit-image-sha384 unit-image-sha3-384 unit-store-sbrk \
5454
unit-tpm-blob unit-policy-create unit-policy-sign unit-rot-auth unit-sdhci-response-bits \
@@ -116,6 +116,13 @@ unit-update-ram:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
116116
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT \
117117
-DPART_SWAP_EXT -DPART_BOOT_EXT -DWOLFBOOT_DUALBOOT -DNO_XIP \
118118
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT -DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
119+
unit-update-ram-nofixed:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN \
120+
-DUNIT_TEST_AUTH -DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH \
121+
-DPART_UPDATE_EXT -DPART_SWAP_EXT -DPART_BOOT_EXT -DWOLFBOOT_DUALBOOT \
122+
-DNO_XIP -DWOLFBOOT_NO_PARTITIONS -DUNIT_TEST_NO_FIXED_PARTITIONS \
123+
-DWOLFBOOT_RAMBOOT_MAX_SIZE=WOLFBOOT_PARTITION_SIZE \
124+
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT \
125+
-DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
119126
unit-update-disk:CFLAGS+=-DMOCK_PARTITIONS -DPRINTF_ENABLED \
120127
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT -DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
121128
unit-string:CFLAGS+=-fno-builtin
@@ -295,6 +302,9 @@ unit-update-flash-enc: ../../include/target.h unit-update-flash.c
295302
unit-update-ram: ../../include/target.h unit-update-ram.c
296303
gcc -o $@ unit-update-ram.c ../../src/image.c $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sha256.c $(CFLAGS) $(LDFLAGS)
297304

305+
unit-update-ram-nofixed: ../../include/target.h unit-update-ram-nofixed.c
306+
gcc -o $@ unit-update-ram-nofixed.c ../../src/image.c $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sha256.c $(CFLAGS) $(LDFLAGS)
307+
298308
unit-update-disk: ../../include/target.h unit-update-disk.c
299309
gcc -o $@ unit-update-disk.c $(CFLAGS) $(LDFLAGS)
300310

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
/* unit-update-ram-nofixed.c
2+
*
3+
* Reproducer for fallback selection in update_ram.c without fixed partitions.
4+
*/
5+
#ifndef WOLFBOOT_HASH_SHA256
6+
#define WOLFBOOT_HASH_SHA256
7+
#endif
8+
9+
#define IMAGE_HEADER_SIZE 256
10+
#define MOCK_ADDRESS_UPDATE 0xCC000000
11+
#define MOCK_ADDRESS_BOOT 0xCD000000
12+
#define MOCK_ADDRESS_SWAP 0xCE000000
13+
#define NO_FORK 1
14+
15+
#include <check.h>
16+
#include <fcntl.h>
17+
#include <stdio.h>
18+
#include <stdlib.h>
19+
#include <sys/mman.h>
20+
#include <unistd.h>
21+
22+
#include "target.h"
23+
24+
static __thread unsigned char
25+
wolfboot_ram[WOLFBOOT_RAMBOOT_MAX_SIZE + IMAGE_HEADER_SIZE];
26+
27+
#define WOLFBOOT_LOAD_ADDRESS (((uintptr_t)wolfboot_ram) + IMAGE_HEADER_SIZE)
28+
#define TEST_SIZE_SMALL 5300
29+
#define DIGEST_TLV_OFF_IN_HDR 28
30+
31+
#include "user_settings.h"
32+
#include "wolfboot/wolfboot.h"
33+
34+
#define wolfBoot_dualboot_candidate_addr wolfBoot_dualboot_candidate_addr_impl
35+
#include "libwolfboot.c"
36+
#undef wolfBoot_dualboot_candidate_addr
37+
38+
static int dualboot_candidate_addr_calls;
39+
40+
int wolfBoot_dualboot_candidate_addr(void** addr)
41+
{
42+
dualboot_candidate_addr_calls++;
43+
ck_assert_msg(dualboot_candidate_addr_calls == 1,
44+
"wolfBoot_dualboot_candidate_addr() called %d times",
45+
dualboot_candidate_addr_calls);
46+
return wolfBoot_dualboot_candidate_addr_impl(addr);
47+
}
48+
49+
#include "update_ram.c"
50+
#include "unit-mock-flash.c"
51+
#include <wolfssl/wolfcrypt/settings.h>
52+
#include <wolfssl/wolfcrypt/sha256.h>
53+
54+
int wolfBoot_staged_ok = 0;
55+
const uint32_t *wolfBoot_stage_address = (uint32_t *)0xFFFFFFFF;
56+
57+
void* hal_get_primary_address(void)
58+
{
59+
return (void *)(uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
60+
}
61+
62+
void* hal_get_update_address(void)
63+
{
64+
return (void *)(uintptr_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
65+
}
66+
67+
void do_boot(const uint32_t *address)
68+
{
69+
struct wolfBoot_image boot_image;
70+
71+
if (wolfBoot_panicked)
72+
return;
73+
74+
wolfBoot_staged_ok++;
75+
wolfBoot_stage_address = address;
76+
ck_assert_uint_eq((uintptr_t)address, WOLFBOOT_LOAD_ADDRESS);
77+
78+
memset(&boot_image, 0, sizeof(boot_image));
79+
ck_assert_int_eq(wolfBoot_open_image_address(&boot_image, wolfboot_ram), 0);
80+
boot_image.hdr = wolfboot_ram;
81+
boot_image.fw_base = (void *)(uintptr_t)WOLFBOOT_LOAD_ADDRESS;
82+
boot_image.part = PART_BOOT;
83+
boot_image.not_ext = 1;
84+
ck_assert_int_eq(wolfBoot_verify_integrity(&boot_image), 0);
85+
}
86+
87+
int hal_flash_protect(haladdr_t address, int len)
88+
{
89+
(void)address;
90+
(void)len;
91+
return 0;
92+
}
93+
94+
static void reset_mock_stats(void)
95+
{
96+
wolfBoot_panicked = 0;
97+
wolfBoot_staged_ok = 0;
98+
dualboot_candidate_addr_calls = 0;
99+
}
100+
101+
static void prepare_flash(void)
102+
{
103+
int ret;
104+
105+
ret = mmap_file("/tmp/wolfboot-unit-ext-file-nofixed.bin",
106+
(void *)(uintptr_t)MOCK_ADDRESS_UPDATE,
107+
WOLFBOOT_PARTITION_SIZE + IMAGE_HEADER_SIZE, NULL);
108+
ck_assert_int_ge(ret, 0);
109+
ret = mmap_file("/tmp/wolfboot-unit-int-file-nofixed.bin",
110+
(void *)(uintptr_t)MOCK_ADDRESS_BOOT,
111+
WOLFBOOT_PARTITION_SIZE + IMAGE_HEADER_SIZE, NULL);
112+
ck_assert_int_ge(ret, 0);
113+
114+
ext_flash_unlock();
115+
ext_flash_erase(WOLFBOOT_PARTITION_BOOT_ADDRESS,
116+
WOLFBOOT_PARTITION_SIZE + IMAGE_HEADER_SIZE);
117+
ext_flash_erase(WOLFBOOT_PARTITION_UPDATE_ADDRESS,
118+
WOLFBOOT_PARTITION_SIZE + IMAGE_HEADER_SIZE);
119+
ext_flash_lock();
120+
}
121+
122+
static void cleanup_flash(void)
123+
{
124+
munmap((void *)WOLFBOOT_PARTITION_BOOT_ADDRESS,
125+
WOLFBOOT_PARTITION_SIZE + IMAGE_HEADER_SIZE);
126+
munmap((void *)WOLFBOOT_PARTITION_UPDATE_ADDRESS,
127+
WOLFBOOT_PARTITION_SIZE + IMAGE_HEADER_SIZE);
128+
}
129+
130+
static int add_payload(uint8_t part, uint32_t version, uint32_t size)
131+
{
132+
uint32_t word;
133+
uint16_t word16;
134+
int i;
135+
uint8_t *base = (uint8_t *)WOLFBOOT_PARTITION_BOOT_ADDRESS;
136+
int ret;
137+
wc_Sha256 sha;
138+
uint8_t digest[SHA256_DIGEST_SIZE];
139+
140+
ret = wc_InitSha256_ex(&sha, NULL, INVALID_DEVID);
141+
if (ret != 0)
142+
return ret;
143+
144+
if (part == PART_UPDATE)
145+
base = (uint8_t *)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
146+
srandom(part);
147+
148+
ext_flash_unlock();
149+
ext_flash_write((uintptr_t)base, "WOLF", 4);
150+
ext_flash_write((uintptr_t)base + 4, (void *)&size, 4);
151+
152+
word = 4 << 16 | HDR_VERSION;
153+
ext_flash_write((uintptr_t)base + 8, (void *)&word, 4);
154+
ext_flash_write((uintptr_t)base + 12, (void *)&version, 4);
155+
156+
word = 2 << 16 | HDR_IMG_TYPE;
157+
ext_flash_write((uintptr_t)base + 16, (void *)&word, 4);
158+
word16 = HDR_IMG_TYPE_AUTH_NONE | HDR_IMG_TYPE_APP;
159+
ext_flash_write((uintptr_t)base + 20, (void *)&word16, 2);
160+
161+
ret = wc_Sha256Update(&sha, base, DIGEST_TLV_OFF_IN_HDR);
162+
if (ret != 0)
163+
return ret;
164+
165+
size += IMAGE_HEADER_SIZE;
166+
for (i = IMAGE_HEADER_SIZE; i < (int)size; i += 4) {
167+
uint32_t rand_word = (random() << 16) | random();
168+
ext_flash_write((uintptr_t)base + i, (void *)&rand_word, 4);
169+
}
170+
for (i = IMAGE_HEADER_SIZE; i < (int)size; i += WOLFBOOT_SHA_BLOCK_SIZE) {
171+
int len = WOLFBOOT_SHA_BLOCK_SIZE;
172+
173+
if (((int)size - i) < len)
174+
len = (int)size - i;
175+
ret = wc_Sha256Update(&sha, base + i, len);
176+
if (ret != 0)
177+
return ret;
178+
}
179+
180+
ret = wc_Sha256Final(&sha, digest);
181+
if (ret != 0)
182+
return ret;
183+
wc_Sha256Free(&sha);
184+
185+
word = SHA256_DIGEST_SIZE << 16 | HDR_SHA256;
186+
ext_flash_write((uintptr_t)base + DIGEST_TLV_OFF_IN_HDR, (void *)&word, 4);
187+
ext_flash_write((uintptr_t)base + DIGEST_TLV_OFF_IN_HDR + 4, digest,
188+
SHA256_DIGEST_SIZE);
189+
ext_flash_lock();
190+
191+
return 0;
192+
}
193+
194+
START_TEST(test_invalid_update_falls_back_to_boot_without_reselect_loop)
195+
{
196+
uint8_t bad_digest[SHA256_DIGEST_SIZE];
197+
198+
reset_mock_stats();
199+
prepare_flash();
200+
ck_assert_int_eq(add_payload(PART_BOOT, 1, TEST_SIZE_SMALL), 0);
201+
ck_assert_int_eq(add_payload(PART_UPDATE, 2, TEST_SIZE_SMALL), 0);
202+
203+
memset(bad_digest, 0xBA, sizeof(bad_digest));
204+
ext_flash_unlock();
205+
ext_flash_write(WOLFBOOT_PARTITION_UPDATE_ADDRESS + DIGEST_TLV_OFF_IN_HDR + 4,
206+
bad_digest, sizeof(bad_digest));
207+
ext_flash_lock();
208+
209+
wolfBoot_start();
210+
211+
ck_assert_int_eq(wolfBoot_staged_ok, 1);
212+
ck_assert_ptr_eq(wolfBoot_stage_address, (const uint32_t *)WOLFBOOT_LOAD_ADDRESS);
213+
cleanup_flash();
214+
}
215+
END_TEST
216+
217+
static Suite *wolfboot_suite(void)
218+
{
219+
Suite *s = suite_create("wolfboot-update-ram-nofixed");
220+
TCase *tc = tcase_create("fallback");
221+
222+
tcase_add_test(tc, test_invalid_update_falls_back_to_boot_without_reselect_loop);
223+
tcase_set_timeout(tc, 5);
224+
suite_add_tcase(s, tc);
225+
226+
return s;
227+
}
228+
229+
int main(int argc, char *argv[])
230+
{
231+
int fails;
232+
Suite *s;
233+
SRunner *sr;
234+
235+
argv0 = strdup(argv[0]);
236+
(void)argc;
237+
238+
s = wolfboot_suite();
239+
sr = srunner_create(s);
240+
#if (NO_FORK == 1)
241+
srunner_set_fork_status(sr, CK_NOFORK);
242+
#endif
243+
srunner_run_all(sr, CK_NORMAL);
244+
fails = srunner_ntests_failed(sr);
245+
srunner_free(sr);
246+
return fails;
247+
}

0 commit comments

Comments
 (0)