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 
23 	if (bufsize < FDT_V1_SIZE)
24 		return -FDT_ERR_TRUNCATED;
25 	err = fdt_check_header(fdt);
26 	if (err != 0)
27 		return err;
28 	if (bufsize < fdt_totalsize(fdt))
29 		return -FDT_ERR_TRUNCATED;
30 
31 	num_memrsv = fdt_num_mem_rsv(fdt);
32 	if (num_memrsv < 0)
33 		return num_memrsv;
34 
35 	while (1) {
36 		offset = nextoffset;
37 		tag = fdt_next_tag(fdt, offset, &nextoffset);
38 
39 		if (nextoffset < 0)
40 			return nextoffset;
41 
42 		switch (tag) {
43 		case FDT_NOP:
44 			break;
45 
46 		case FDT_END:
47 			if (depth != 0)
48 				return -FDT_ERR_BADSTRUCTURE;
49 			return 0;
50 
51 		case FDT_BEGIN_NODE:
52 			depth++;
53 			if (depth > INT_MAX)
54 				return -FDT_ERR_BADSTRUCTURE;
55 			break;
56 
57 		case FDT_END_NODE:
58 			if (depth == 0)
59 				return -FDT_ERR_BADSTRUCTURE;
60 			depth--;
61 			break;
62 
63 		case FDT_PROP:
64 			prop = fdt_getprop_by_offset(fdt, offset, &propname,
65 						     &err);
66 			if (!prop)
67 				return err;
68 			break;
69 
70 		default:
71 			return -FDT_ERR_INTERNAL;
72 		}
73 	}
74 }
75