dtc/libfdt/fdt_check.c
Tom Rini 66e1201c37
Some checks are pending
Build test / build-linux (make, alpine) (push) Waiting to run
Build test / build-linux (make, archlinux) (push) Waiting to run
Build test / build-linux (make, fedora) (push) Waiting to run
Build test / build-linux (make, ubuntu) (push) Waiting to run
Build test / build-linux (meson, alpine) (push) Waiting to run
Build test / build-linux (meson, archlinux) (push) Waiting to run
Build test / build-linux (meson, fedora) (push) Waiting to run
Build test / build-linux (meson, ubuntu) (push) Waiting to run
Build test / build-macos (make) (push) Waiting to run
Build test / build-macos (meson) (push) Waiting to run
Build test / mingw32 (push) Waiting to run
Build test / clang64 (push) Waiting to run
Build test / mingw64 (push) Waiting to run
Build test / ucrt64 (push) Waiting to run
Build test / FreeBSD 13.5 make build (push) Waiting to run
Build test / FreeBSD 14.3 make build (push) Waiting to run
Build test / FreeBSD 13.5 meson build (push) Waiting to run
Build test / FreeBSD 14.3 meson build (push) Waiting to run
libfdt: fdt_check_full: Add can_assume(PERFECT) check
In this function from fdt_check.c we have (reasonably and as the name
implies) a number of checks on the DTB. However, there are cases where
we may wish to assume that we have been given a perfect DTB already and
do nothing here. Add a test for can_assume(PERFECT) as the first check
in this function and if true, perform no checks.

Signed-off-by: Tom Rini <trini@konsulko.com>
Message-ID: <20260526203022.4006434-1-trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2026-06-17 15:31:29 +10:00

98 lines
1.9 KiB
C

// 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 (can_assume(PERFECT))
return 0;
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 && tag != FDT_NOP)
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)
return 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;
}
}
}