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