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