1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3 * libfdt - Flat Device Tree manipulation
4 * Testcase for fdt_check_header
5 * Copyright (C) 2018 David Gibson
6 */
7
8 #include <stdio.h>
9
10 #include <libfdt.h>
11
12 #include "tests.h"
13
dtdup(void * dt)14 static void *dtdup(void *dt)
15 {
16 size_t bufsize = fdt_totalsize(dt);
17 void *buf = xmalloc(bufsize);
18 fdt_move(dt, buf, bufsize);
19 return buf;
20 }
21
22 #define CHECK_MANGLE(exerr, code) \
23 do { \
24 void *fdt = dtdup(template); \
25 { code } \
26 err = fdt_check_header(fdt); \
27 verbose_printf("\"%s\" => %s\n", #code, fdt_strerror(err)); \
28 if (err != (exerr)) \
29 FAIL("fdt_check_header() didn't catch mangle %s", \
30 #code); \
31 free(fdt); \
32 } while (0)
33
main(int argc,char * argv[])34 int main(int argc, char *argv[])
35 {
36 void *template;
37 int err;
38
39 test_init(argc, argv);
40 template = load_blob(argv[1]);
41
42 /* Check that the base dt is valid before mangling it */
43 err = fdt_check_header(template);
44 if (err != 0)
45 FAIL("Base tree fails: %s", fdt_strerror(err));
46
47 /* Check a no-op mangle doesn't break things */
48 CHECK_MANGLE(0, ; );
49
50 /* Mess up the magic number */
51 CHECK_MANGLE(-FDT_ERR_BADMAGIC,
52 fdt_set_magic(fdt, fdt_magic(fdt) ^ 0x1);
53 );
54 CHECK_MANGLE(-FDT_ERR_BADMAGIC,
55 fdt_set_magic(fdt, fdt_magic(fdt) ^ 0x80000000);
56 );
57
58 /* Mess up the version */
59 CHECK_MANGLE(-FDT_ERR_BADVERSION,
60 fdt_set_version(fdt, FDT_FIRST_SUPPORTED_VERSION - 1);
61 fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION - 1);
62 );
63 CHECK_MANGLE(-FDT_ERR_BADVERSION,
64 fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION + 1);
65 fdt_set_last_comp_version(fdt, FDT_LAST_SUPPORTED_VERSION + 1);
66 );
67 CHECK_MANGLE(-FDT_ERR_BADVERSION,
68 fdt_set_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
69 fdt_set_last_comp_version(fdt, FDT_LAST_SUPPORTED_VERSION);
70 );
71
72 /* Out of bounds sizes */
73 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
74 fdt_set_totalsize(fdt, FDT_V1_SIZE - 1);
75 );
76 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
77 fdt_set_totalsize(fdt, (uint32_t)INT_MAX + 1);
78 );
79
80 /* Truncate within various blocks */
81 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
82 fdt_set_totalsize(fdt, fdt_off_dt_struct(fdt) - 1);
83 );
84 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
85 fdt_set_totalsize(fdt, fdt_off_dt_strings(fdt) - 1);
86 );
87 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
88 fdt_set_totalsize(fdt, fdt_off_mem_rsvmap(fdt) - 1);
89 );
90 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
91 fdt_set_totalsize(fdt, fdt_off_dt_struct(fdt) + 1);
92 );
93 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
94 fdt_set_totalsize(fdt, fdt_off_dt_strings(fdt) + 1);
95 );
96 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
97 fdt_set_totalsize(fdt, fdt_off_mem_rsvmap(fdt) + 1);
98 );
99
100 /* Negative block sizes */
101 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
102 fdt_set_size_dt_struct(fdt, (uint32_t)-1);
103 );
104 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
105 fdt_set_size_dt_strings(fdt, (uint32_t)-1);
106 );
107 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
108 fdt_set_size_dt_struct(fdt, (uint32_t)INT_MIN);
109 );
110 CHECK_MANGLE(-FDT_ERR_TRUNCATED,
111 fdt_set_size_dt_strings(fdt, (uint32_t)INT_MIN);
112 );
113
114 PASS();
115 }
116