123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
- /*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- */
- #include "libfdt_env.h"
- #include <fdt.h>
- #include <libfdt.h>
- #include "libfdt_internal.h"
- int fdt_check_full(const void *fdt, size_t bufsize)
- {
- int err;
- int num_memrsv;
- int offset, nextoffset = 0;
- uint32_t tag;
- unsigned int depth = 0;
- const void *prop;
- const char *propname;
- bool expect_end = false;
- if (bufsize < FDT_V1_SIZE)
- return -FDT_ERR_TRUNCATED;
- if (bufsize < fdt_header_size(fdt))
- return -FDT_ERR_TRUNCATED;
- err = fdt_check_header(fdt);
- if (err != 0)
- return err;
- if (bufsize < fdt_totalsize(fdt))
- return -FDT_ERR_TRUNCATED;
- num_memrsv = fdt_num_mem_rsv(fdt);
- if (num_memrsv < 0)
- return num_memrsv;
- while (1) {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
- if (nextoffset < 0)
- return nextoffset;
- /* If we see two root nodes, something is wrong */
- if (expect_end && tag != FDT_END)
- return -FDT_ERR_BADSTRUCTURE;
- switch (tag) {
- case FDT_NOP:
- break;
- case FDT_END:
- if (depth != 0)
- return -FDT_ERR_BADSTRUCTURE;
- return 0;
- case FDT_BEGIN_NODE:
- depth++;
- if (depth > INT_MAX)
- return -FDT_ERR_BADSTRUCTURE;
- /* The root node must have an empty name */
- if (depth == 1) {
- const char *name;
- int len;
- name = fdt_get_name(fdt, offset, &len);
- if (*name || len)
- return -FDT_ERR_BADSTRUCTURE;
- }
- break;
- case FDT_END_NODE:
- if (depth == 0)
- return -FDT_ERR_BADSTRUCTURE;
- depth--;
- if (depth == 0)
- expect_end = true;
- break;
- case FDT_PROP:
- prop = fdt_getprop_by_offset(fdt, offset, &propname,
- &err);
- if (!prop)
- return err;
- break;
- default:
- return -FDT_ERR_INTERNAL;
- }
- }
- }
|