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