The root node is supposed to have an empty name, but at present this is
not checked. The behaviour of such a tree is not well defined. Most
software rightly assumes that the root node is at offset 0 and does not
check the name. This oddity was discovered as part of a security
investigation into U-Boot verified boot.
Add a check for this to fdt_check_full().
Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Arie Haenel <arie.haenel@intel.com>
Reported-by: Julien Lenoir <julien.lenoir@intel.com>
Message-Id: <20210323010410.3222701-2-sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
At present it is possible to have two root nodes and even access nodes
in the 'second' root. Such trees should not be considered valid. This
was discovered as part of a security investigation into U-Boot verified
boot.
Add a check for this to fdt_check_full().
Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Arie Haenel <arie.haenel@intel.com>
Reported-by: Julien Lenoir <julien.lenoir@intel.com>
Message-Id: <20210323000926.3210733-1-sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This function will append an address range property using parent node's
"#address-cells" and "#size-cells" properties.
It will be used in implementing kdump with kexec_file_load system call
at linux kernel for arm64 once it is merged into kernel tree.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Message-Id: <20190327061552.17170-2-takahiro.akashi@linaro.org>
[dwg: Correct a SEGV error in the testcase]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
fdt_num_mem_rsv() and fdt_get_mem_rsv() currently don't sanity check their
parameters, or the memory reserve section offset in the header. That means
that on a corrupted blob they could access outside of the range of memory
that they should.
This improves their safety checking, meaning they shouldn't access outside
the blob's bounds, even if its contents are badly corrupted.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Simon Glass <sjg@chromium.org>
fdt_string() is used to retrieve strings from a DT blob's strings section.
It's rarely used directly, but is widely used internally.
However, it doesn't do any bounds checking, which means in the case of a
corrupted blob it could access bad memory, which libfdt is supposed to
avoid.
This write a safe alternative to fdt_string, fdt_get_string(). It checks
both that the given offset is within the string section and that the string
it points to is properly \0 terminated within the section. It also returns
the string's length as a convenience (since it needs to determine to do the
checks anyway).
fdt_string() is rewritten in terms of fdt_get_string() for compatibility.
Most of the diff here is actually testing infrastructure.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
In a number of places, dtc and associated tools and test code use
leading _ characters on identifiers to flag them as "internal", an
idiom taken from the Linux kernel. This is a bad idea in a userspace
program, because identifiers with a leading _ are reserved for the C
library / system.
In some cases, the extra _ served no real purpose, so simply drop it. In
others move to the end of the identifier, which is a convention we're free
to use for our own purposes.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
For testing we (ab)use the assembler to build us a sample dtb, independent
of the other tools (dtc and libfdt) that we're trying to test. In a few
places this uses 64-bit arithmetic to decompose 64-bit constants into
the individual bytes in the blob.
Unfortunately, it seems that some builds of GNU as don't support >32 bit
arithmetic, though it's not entirely clear to me which do and which don't
(Fedora i386 does support 64-bit, Debian arm32 doesn't).
Anyway, to be safe, this avoids 64-bit arithmetic in assembler at the cost
of some extra awkwardness because we have to define the values in 32-bit
halves.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Add a function to modify inplace only a portion of a property..
This is especially useful when the property is an array of values, and you
want to update one of them without changing the DT size.
Acked-by: Simon Glass <sjg@chromium.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
[dwg: Remove unnecessary unsigned qualifier, correct a comment]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
We have a couple of checks of the form:
if (offset+size > totalsize)
die();
We need to check that offset+size doesn't overflow, otherwise the check
will pass, and we may access past totalsize.
Found with AFL.
Signed-off-by: Anton Blanchard <anton@samba.org>
[Added a testcase]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
In device trees in the world, properties consisting of a single 64-bit
integer are not as common as those consisting of a single 32-bit, cell
sized integer, but they're common enough that they're worth including
convenience functions for.
This patch adds helper wrappers of fdt_setprop_inplace(), fdt_setprop() and
fdt_appendprop() for handling 64-bit integer quantities in properties. For
better consistency with the names of these new *_u64() functions we also
add *_u32() functions as alternative names for the existing *_cell()
functions handling 32-bit integers.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With this patch the following property assignment:
property = <0x12345678 'a' '\r' 100>;
is equivalent to:
property = <0x12345678 0x00000061 0x0000000D 0x00000064>
Signed-off-by: Anton Staaf <robotboy@chromium.org>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
I've recently worked with a FreeBSD developer, getting dtc and libfdt
working on FreeBSD. This showed up a number of portability problems
in the dtc package which this patch addresses. Changes are as
follows:
- the parent_offset and supernode_atdepth_offset testcases
used the glibc extension functions strchrnul() and strndupa(). Those
are removed, using slightly longer coding with standard C functions
instead.
- some other testcases had a #define _GNU_SOURCE for no
particular reason. This is removed.
- run_tests.sh has bash specific constructs removed, and the
interpreter changed to /bin/sh. This apparently now runs fine on
FreeBSD's /bin/sh, and I've also tested it with both ash and dash.
- convert-dtsv0-lexer.l has some extra #includes added. These
must have been included indirectly with Linux and glibc, but aren't on
FreeBSD.
- the endian handling functions in libfdt_env.h, based on
endian.h and byteswap.h are replaced with some portable open-coded
versions. Unfortunately, these result in fairly crappy code when
compiled, but as far as I can determine there doesn't seem to be any
POSIX, SUS or de facto standard way of determining endianness at
compile time, nor standard names for byteswapping functions.
- some more endian handling, from testdata.h using the
problematic endian.h is simply removed, since it wasn't actually being
used anyway.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This patch adds checks to the checking framework to verify that node
and property names contain only legal characters, and in the case of
node names there is at most one '@'.
At present when coming from dts input, this is mostly already ensured
by the grammer, however putting the check later means its easier to
generate helpful error messages rather than just "syntax error". For
dtb input, these checks replace the older similar check built into
flattree.c.
Testcases for the checks are also implemented.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
In a number of places through libfdt and its tests, we have *_typed()
macro variants on functions which use gcc's typeof and statement
expression extensions to allow passing literals where the underlying
function takes a buffer and size.
These seemed like a good idea at the time, but in fact they have some
problems. They use typeof and statement expressions, extensions I'd
prefer to avoid for portability. Plus, they have potential gotchas -
although they'll deal with the size of the thing passed, they won't
deal with other representation issues (like endianness) and results
could be very strange if the type of the expression passed isn't what
you think it is.
In fact, the only users of these _typed() macros were when the value
passed is a single cell (32-bit integer). Therefore, this patch
removes all these _typed() macros and replaces them with explicit
_cell() variants which handle a single 32-bit integer, and which also
perform endian convesions as appropriate.
With this in place, it now becomes easy to use standardized big-endian
representation for integer valued properties in the testcases,
regardless of the platform we're running on. We therefore do that,
which has the additional advantage that all the example trees created
during a test run are now byte-for-byte identical regardless of
platform.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This patch adds fdt_get_phandle() and fdt_node_offset_by_phandle()
functions to libfdt. fdt_get_phandle() will retreive the phandle
value of a given node, and fdt_node_offset_by_phandle() will locate a
node given a phandle.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This patch alters the main testcase, and the dts file corresponding to
it so that we at least trivially exercise dtc's bytestring and base
conversion features.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This patch makes improvements to the way properties are printed when
in dtc is producing dts output.
- Characters which need escaping are now properly handled when
printing properties as strings
- The heuristics for what format to use for a property are
improved so that 'compatible' properties will be displayed as
expected.
- escapes.dts is altered to better demonstrate the changes,
and the string_escapes testcase is adjusted accordingly.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
dtc supports the use of C-style escapes (\n, \t and so forth) in
string property definitions via the data_copy_escape_string()
function. However, while it supports the most common escape
characters, it doesn't support the full set that C does, which is a
potential gotcha.
Worse, a bug in the lexer means that while data_copy_escape_string()
can handle the \" escape, a string with such an escape won't lex
correctly.
This patch fixes both problems, extending data_copy_escape_string() to
support the missing escapes, and fixing the regex for strings in the
lexer to handle internal escaped quotes.
This also adds a testcase for string escape functionality.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This patch adds functions to libfdt for accessing the memory
reservation map section of a device tree blob. fdt_num_mem_rsv()
retreives the number of reservation entries in a dtb, and
fdt_get_mem_rsv() retreives a specific reservation entry.
fdt_add_mem_rsv() adds a new entry, and fdt_del_mem_rsv() removes a
specific numbered entry.
Testcases for these new functions are also included.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Flat device trees always have integers in their structure stored as
big-endian. From this point of view, property values are
bags-of-bytes and any endianness is up to users of the device tree to
determine.
The libfdt testcases which use properties with integer values,
currently use native endian format for the architecture on which the
testcases are run. This works ok for now, since both the creation and
checking of the example device trees happen in the same endianness.
This will become a problem, however, for tests of dtc which we want to
add in the nearish future. dtc always uses big-endian format for
'cell' format data in properties; as it needs to in order to produce
powerpc-usable device trees when hosted on a little-endian
architecture.
This patch, therefore, changes the libfdt testsuite to use big-endian
format always for integer format data, in order to interoperate sanely
with future dtc testcases. This also means that the example trees
created by the testsuite should now be byte-for-byte identical
regardless of dtc and libfdt's host platform, which is arguably an
advantage.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The libfdt functions are supposed to behave tolerably well when practical,
even if given a corrupted device tree as input. A silly mistake in
fdt_get_property() means we're bounds checking against the size of a pointer
instead of the size of a property header, meaning we can get bogus
behaviour in a corrupted device tree where the structure block ends in
what's supposed to be the middle of a property.
This patch corrects the problem (fdt_get_property() will now return
BADSTRUCTURE in this case), and also adds a testcase to catch the bug.