Skip to content

Commit cd7cb79

Browse files
committed
Validate FDT string offsets
F/1481
1 parent 9a5fbee commit cd7cb79

File tree

3 files changed

+111
-3
lines changed

3 files changed

+111
-3
lines changed

src/fdt.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,9 +522,26 @@ const char* fdt_get_name(const void *fdt, int nodeoffset, int *len)
522522

523523
const char* fdt_get_string(const void *fdt, int stroffset, int *lenp)
524524
{
525-
const char *s = (const char*)fdt + fdt_off_dt_strings(fdt) + stroffset;
525+
uint32_t strsize = fdt_size_dt_strings(fdt);
526+
const char *s;
527+
const char *end;
528+
529+
if ((stroffset < 0) || ((uint32_t)stroffset >= strsize)) {
530+
if (lenp)
531+
*lenp = -FDT_ERR_BADOFFSET;
532+
return NULL;
533+
}
534+
535+
s = (const char*)fdt + fdt_off_dt_strings(fdt) + stroffset;
536+
end = memchr(s, '\0', strsize - (uint32_t)stroffset);
537+
if (end == NULL) {
538+
if (lenp)
539+
*lenp = -FDT_ERR_BADSTRUCTURE;
540+
return NULL;
541+
}
542+
526543
if (lenp) {
527-
*lenp = (int)strlen(s);
544+
*lenp = (int)(end - s);
528545
}
529546
return s;
530547
}

tools/unit-tests/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ endif
4242

4343

4444

45-
TESTS:=unit-parser unit-extflash unit-string unit-spi-flash unit-aes128 \
45+
TESTS:=unit-parser unit-fdt unit-extflash unit-string unit-spi-flash unit-aes128 \
4646
unit-aes256 unit-chacha20 unit-pci unit-mock-state unit-sectorflags \
4747
unit-image unit-image-rsa unit-nvm unit-nvm-flagshome unit-enc-nvm \
4848
unit-enc-nvm-flagshome unit-delta unit-update-flash \
@@ -79,6 +79,7 @@ unit-aes128:CFLAGS+=-DEXT_ENCRYPTED -DENCRYPT_WITH_AES128
7979
unit-aes256:CFLAGS+=-DEXT_ENCRYPTED -DENCRYPT_WITH_AES256
8080
unit-chacha20:CFLAGS+=-DEXT_ENCRYPTED -DENCRYPT_WITH_CHACHA
8181
unit-parser:CFLAGS+=-DNVM_FLASH_WRITEONCE
82+
unit-fdt:CFLAGS+=-DWOLFBOOT_FDT
8283
unit-nvm:CFLAGS+=-DNVM_FLASH_WRITEONCE -DMOCK_PARTITIONS
8384
unit-nvm-flagshome:CFLAGS+=-DNVM_FLASH_WRITEONCE -DMOCK_PARTITIONS -DFLAGS_HOME
8485
unit-enc-nvm:CFLAGS+=-DNVM_FLASH_WRITEONCE -DMOCK_PARTITIONS -DEXT_ENCRYPTED \
@@ -112,6 +113,10 @@ unit-extflash.o: FORCE
112113
unit-parser: ../../include/target.h unit-parser.c
113114
gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
114115

116+
unit-fdt: ../../include/target.h unit-fdt.c ../../src/fdt.c
117+
gcc -o $@ $^ $(CFLAGS) -ffunction-sections -fdata-sections $(LDFLAGS) \
118+
-Wl,--gc-sections
119+
115120
unit-extflash: ../../include/target.h unit-extflash.c
116121
gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
117122

tools/unit-tests/unit-fdt.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/* unit-fdt.c
2+
*
3+
* Unit tests for flattened device tree helpers.
4+
*/
5+
6+
#include <check.h>
7+
#include <stdint.h>
8+
#include <string.h>
9+
10+
#include "../../include/fdt.h"
11+
12+
void wolfBoot_printf(const char *fmt, ...)
13+
{
14+
(void)fmt;
15+
}
16+
17+
START_TEST(test_fdt_get_string_rejects_out_of_range_offset)
18+
{
19+
struct {
20+
struct fdt_header hdr;
21+
char strings[8];
22+
char after[4];
23+
} blob;
24+
int len = 1234;
25+
const char *s;
26+
27+
memset(&blob, 0, sizeof(blob));
28+
fdt_set_off_dt_strings(&blob, sizeof(blob.hdr));
29+
fdt_set_size_dt_strings(&blob, sizeof(blob.strings));
30+
memcpy(blob.strings, "chosen", sizeof("chosen"));
31+
blob.after[0] = 'X';
32+
blob.after[1] = '\0';
33+
34+
s = fdt_get_string(&blob, (int)sizeof(blob.strings), &len);
35+
36+
ck_assert_ptr_null(s);
37+
ck_assert_int_eq(len, -FDT_ERR_BADOFFSET);
38+
}
39+
END_TEST
40+
41+
START_TEST(test_fdt_get_string_returns_string_with_valid_offset)
42+
{
43+
struct {
44+
struct fdt_header hdr;
45+
char strings[16];
46+
} blob;
47+
int len = -1;
48+
const char *s;
49+
50+
memset(&blob, 0, sizeof(blob));
51+
fdt_set_off_dt_strings(&blob, sizeof(blob.hdr));
52+
fdt_set_size_dt_strings(&blob, sizeof(blob.strings));
53+
memcpy(blob.strings, "serial\0console\0", 15);
54+
55+
s = fdt_get_string(&blob, 7, &len);
56+
57+
ck_assert_ptr_nonnull(s);
58+
ck_assert_str_eq(s, "console");
59+
ck_assert_int_eq(len, 7);
60+
}
61+
END_TEST
62+
63+
static Suite *fdt_suite(void)
64+
{
65+
Suite *s = suite_create("fdt");
66+
TCase *tc = tcase_create("fdt");
67+
68+
tcase_add_test(tc, test_fdt_get_string_rejects_out_of_range_offset);
69+
tcase_add_test(tc, test_fdt_get_string_returns_string_with_valid_offset);
70+
suite_add_tcase(s, tc);
71+
72+
return s;
73+
}
74+
75+
int main(void)
76+
{
77+
int fails;
78+
Suite *s = fdt_suite();
79+
SRunner *sr = srunner_create(s);
80+
81+
srunner_run_all(sr, CK_NORMAL);
82+
fails = srunner_ntests_failed(sr);
83+
srunner_free(sr);
84+
85+
return fails;
86+
}

0 commit comments

Comments
 (0)