• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
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 
11 #include "libfdt_internal.h"
12 
fdt_check_full(const void * fdt,size_t bufsize)13 int fdt_check_full(const void *fdt, size_t bufsize)
14 {
15 	int err;
16 	int num_memrsv;
17 	int offset, nextoffset = 0;
18 	uint32_t tag;
19 	unsigned int depth = 0;
20 	const void *prop;
21 	const char *propname;
22 	bool expect_end = false;
23 
24 	if (bufsize < FDT_V1_SIZE)
25 		return -FDT_ERR_TRUNCATED;
26 	if (bufsize < fdt_header_size(fdt))
27 		return -FDT_ERR_TRUNCATED;
28 	err = fdt_check_header(fdt);
29 	if (err != 0)
30 		return err;
31 	if (bufsize < fdt_totalsize(fdt))
32 		return -FDT_ERR_TRUNCATED;
33 
34 	num_memrsv = fdt_num_mem_rsv(fdt);
35 	if (num_memrsv < 0)
36 		return num_memrsv;
37 
38 	while (1) {
39 		offset = nextoffset;
40 		tag = fdt_next_tag(fdt, offset, &nextoffset);
41 
42 		if (nextoffset < 0)
43 			return nextoffset;
44 
45 		/* If we see two root nodes, something is wrong */
46 		if (expect_end && tag != FDT_END)
47 			return -FDT_ERR_BADSTRUCTURE;
48 
49 		switch (tag) {
50 		case FDT_NOP:
51 			break;
52 
53 		case FDT_END:
54 			if (depth != 0)
55 				return -FDT_ERR_BADSTRUCTURE;
56 			return 0;
57 
58 		case FDT_BEGIN_NODE:
59 			depth++;
60 			if (depth > INT_MAX)
61 				return -FDT_ERR_BADSTRUCTURE;
62 
63 			/* The root node must have an empty name */
64 			if (depth == 1) {
65 				const char *name;
66 				int len;
67 
68 				name = fdt_get_name(fdt, offset, &len);
69 				if (!name || *name || len)
70 					return -FDT_ERR_BADSTRUCTURE;
71 			}
72 			break;
73 
74 		case FDT_END_NODE:
75 			if (depth == 0)
76 				return -FDT_ERR_BADSTRUCTURE;
77 			depth--;
78 			if (depth == 0)
79 				expect_end = true;
80 			break;
81 
82 		case FDT_PROP:
83 			prop = fdt_getprop_by_offset(fdt, offset, &propname,
84 						     &err);
85 			if (!prop)
86 				return err;
87 			break;
88 
89 		default:
90 			return -FDT_ERR_INTERNAL;
91 		}
92 	}
93 }
94