blob: 8b43936b35fe76c1c4acadc486a2e8cfcff0df94 [file] [log] [blame]
rjw2e8229f2022-02-15 21:08:12 +08001// SPDX-License-Identifier: MIT
2/*
3 * libfdt - Flat Device Tree manipulation
4 * Copyright (C) 2006 David Gibson, IBM Corporation.
5 */
6#include "libfdt_env.h"
7
8#include <fdt.h>
9#include <libfdt.h>
10#include <stdbool.h>
11
12#include "libfdt_internal.h"
13
14int fdt_check_full(const void *fdt, size_t bufsize)
15{
16 int err;
17 int num_memrsv;
18 int offset, nextoffset = 0;
19 uint32_t tag;
20 unsigned int depth = 0;
21 const void *prop;
22 const char *propname;
23 bool expect_end = false;
24
25 if (bufsize < FDT_V1_SIZE)
26 return -FDT_ERR_TRUNCATED;
27 if (bufsize < fdt_header_size(fdt))
28 return -FDT_ERR_TRUNCATED;
29 err = fdt_check_header(fdt);
30 if (err != 0)
31 return err;
32 if (bufsize < fdt_totalsize(fdt))
33 return -FDT_ERR_TRUNCATED;
34
35 num_memrsv = fdt_num_mem_rsv(fdt);
36 if (num_memrsv < 0)
37 return num_memrsv;
38
39 while (1) {
40 offset = nextoffset;
41 tag = fdt_next_tag(fdt, offset, &nextoffset);
42
43 if (nextoffset < 0)
44 return nextoffset;
45
46 /* If we see two root nodes, something is wrong */
47 if (expect_end && tag != FDT_END)
48 return -FDT_ERR_BADSTRUCTURE;
49
50 switch (tag) {
51 case FDT_NOP:
52 break;
53
54 case FDT_END:
55 if (depth != 0)
56 return -FDT_ERR_BADSTRUCTURE;
57 return 0;
58
59 case FDT_BEGIN_NODE:
60 depth++;
61 if (depth > INT_MAX)
62 return -FDT_ERR_BADSTRUCTURE;
63
64 /* The root node must have an empty name */
65 if (depth == 1) {
66 const char *name;
67 int len;
68
69 name = fdt_get_name(fdt, offset, &len);
70 if (*name || len)
71 return -FDT_ERR_BADSTRUCTURE;
72 }
73 break;
74
75 case FDT_END_NODE:
76 if (depth == 0)
77 return -FDT_ERR_BADSTRUCTURE;
78 depth--;
79 if (depth == 0)
80 expect_end = true;
81 break;
82
83 case FDT_PROP:
84 prop = fdt_getprop_by_offset(fdt, offset, &propname,
85 &err);
86 if (!prop)
87 return err;
88 break;
89
90 default:
91 return -FDT_ERR_INTERNAL;
92 }
93 }
94}