Validator#5
Conversation
✅ Deploy Preview for fluffy-chebakia-3fa329 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Result from test by Chasel: fdtdump UniversalPayload.fit **** fdtdump is a low-level debugging tool, not meant for general use. /dts-v1/; / { python fit_validate.py ../UniversalPayload.fit ../UniversalPayload.fit: |
|
My guess is that the line endings are not working and this is running on Windows. I will need to break out my Windows VM and figure out what is missing |
✅ Deploy Preview for fluffy-chebakia-3fa329 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Add the build/ directory to this file so that it doesn't show up in 'git status'. Signed-off-by: Simon Glass <sjg@chromium.org>
There is currently no easy way to check whether a FIT conforms to the
specification. Detection of malformed images is left to consuming tools
and manual inspection.
Add an initial Python-based validator that checks a binary FIT against
a hand-written schema. It does not yet cover the full specification but
provides the framework on which to expand.
Invoke it as:
python3 -m fit_validate.validate <filename>
A 'check' target in the Makefile runs the unit tests and pylint over
the validator sources.
Signed-off-by: Simon Glass <sjg@chromium.org>
Some FIT producers emit property names with stray leading or trailing whitespace, for example by splitting a DTS-style 'name = "value"' line on '=' without strip()-ing the left-hand side. A binary FIT carries those names verbatim, so the validator currently reports a generic 'Unexpected property' diagnostic that buries the real issue under the list of valid schema properties. Detect property names where strip() changes the value and emit a specific diagnostic that names the producer as the likely culprit. If the stripped name matches a property in the schema, include a 'did you mean' hint to point straight at the fix. Add a unit test that builds a binary FIT directly with libfdt (since dtc strips whitespace from names during compilation) and asserts the new diagnostics fire. Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hash and signature subnodes inside images and configurations are mandatory parts of every signed FIT and the spec defines their structure precisely (chapter 5, sections 'Hash nodes', 'Image-signature nodes' and 'Configuration-signature nodes'). The validator currently has no schema for them, so any well-formed signed FIT silently slips through with no checking of these subtrees. Add the missing schema: * hash-N: requires 'algo' (one of crc16-ccitt, crc32, md5, sha1, sha256, sha384, sha512) and 'value'. * signature-N under an image: requires algo, key-name-hint, value, hashed-nodes and hashed-strings; optional sign-images, timestamp, signer-name, signer-version, comment, padding (pkcs-1.5 or pss). * signature-N under a config: requires algo, key-name-hint and value; optional sign-images and the same metadata fields. This also needs two pieces of supporting work: 1. get_element() currently returns the first NodeAny child regardless of name pattern, so a schema scope can only have one pattern-matched subnode shape. Filter NodeAny siblings by pattern when more than one is present. 2. Add PropBytes for opaque byte values such as hash digests and signature blobs. PropDesc works but its inherited __init__ takes prop_type as the second positional argument, making PropDesc(name, True) silently set prop_type=True instead of required=True. PropBytes wraps the awkward calling convention. Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Many FIT misconfigurations come from a typo in the value of a string property that names another node: 'firmware = "image-x"' where there is no /images/image-x, a 'default = "conf-99"' that points at no existing config, a 'loadables' entry that has been deleted from the images list, and so on. The validator currently treats these as plain strings and lets the broken reference through. Add three new schema element types that walk the FDT to confirm the target exists: * PropImageRef: value names a /images/<name>. Used for fdt, kernel, ramdisk, firmware and image-data. * PropConfigRef: value names a /configurations/<name>. Used for the configurations 'default' property. * PropImageRefList: each item of a stringlist names an image. Used for loadables and the signature 'sign-images' list. Also wire the no-chain rule for image-data (chapter 5: 'The target node must not itself have an image-data property; chains of references are not permitted'). Fix the conditional_props on data, data-offset and data-size so they also treat image-data as an alternative source of image bytes - an authored FIT with image-data and no data-* should not be flagged as missing data-offset. Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The schema is too lax in two ways. Property values that the spec defines as closed enumerations - type, arch, os, compression - are accepted as free strings, so a typo such as arch='z80' or compression='snappy' produces a FIT that the validator passes. And properties that the spec marks as conditionally mandatory (os only required for type=kernel, arch for a specific list of types, entry and load for firmware and kernel) are either always-required or always-optional, neither of which matches the spec. Add a 'values' option to PropString so a property can declare its list of allowed values directly. Apply it to type, arch, os and compression on image nodes. Add a 'required_when' option that makes a property required only when a sibling has one of a listed set of values. Use it for arch (when type is one of standalone, kernel, firmware, ramdisk, fdt), os (when type=kernel) and entry/load (when type is firmware or kernel). Relax the root description from required to optional, matching the spec. Update the test fixtures to be spec-compliant kernel images (with load and entry) and add tests for the new behaviour: type-driven requirement gating, value-set rejection, and the now-optional root description. Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The schema is still missing several properties that the spec defines. On image nodes: data-position (machine address as an alternative to data-offset), phase (spl or u-boot, recent commit 1e69f6b) and compatible (the loading-method string, mandatory for fpga images and images without a load address). On configuration nodes: cmdline (the kernel command line, commit 248258c), fpga and script image references, and load-only (commit 1be2a60). Add them all. The data-position property is treated as an alternative to data and image-data, so the conditional_props on data-offset and data are extended to skip their requirement when data-position is set. compatible on an image becomes required when type='fpga'; its value list is left unconstrained because the spec only enumerates the fpga loading methods and compatible serves a wider role for images without a load address. Pipe required_when through PropStringList so compatible can use the same type-driven requirement gate as the other image properties. Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The command-line test invokes the validator as a subprocess via the 'python' binary, which is not present on Ubuntu and other systems that ship only 'python3'. Use sys.executable so the test runs under whichever interpreter the test suite itself is using. Also rename test_comannd_line to test_command_line; the typo makes the test harder to pick out by name. Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
require-fit is a Universal Payload extension and is not defined by the FIT specification. It currently lives in the shared config schema, so the validator silently accepts it on a plain FIT - which is misleading, since other FIT consumers will not understand the property. Move require-fit to the UPL branch of get_schema(), alongside the existing UPL-only project and firmware additions. Also pick the schema per file. Files whose name ends in .upl are validated against the UPL schema automatically; the rest default to FIT. The -u flag still forces UPL globally for callers that want the old behaviour. This means a UPL FIT can be checked just by giving it a .upl extension, without having to pass the -u flag. Co-developed-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Simon Glass <sjg@chromium.org>
Summary
A Python-based validator for Flat Image Tree (FIT) files. The validator
walks a binary FIT (or compiles a
.dtssource on the fly) and reportserrors against a schema derived from
chapter5-source-file-format.rst.It selects the schema per file:
.upl-suffixed files are checkedagainst the Universal Payload (UPL) variant; everything else uses the
plain FIT schema. The
-uflag forces UPL globally for callers thatprefer it.
What is checked
/,/images/<image>and/configurations/<config>—required and optional properties per the spec, including
type-conditional requirements (
osonly fortype=kernel;archfor standalone/kernel/firmware/ramdisk/fdt;
entry/loadforfirmware/kernel;
compatiblemandatory on fpga images).type,arch,os,compressionandphaseare checked against the spec's enumerations.hash-N) —algo(crc16-ccitt | crc32 | md5 |sha1 | sha256 | sha384 | sha512) and
valueare required.signature-N) — compositealgo(
<hash>,<rsa|ecdsa>NNNN),key-name-hint,valueplus thesigning-time metadata (hashed-nodes, hashed-strings, signer-name,
padding pkcs-1.5 / pss, etc.) per the image- and configuration-
signature sections of the spec.
defaultin/configurationsmust name anexisting configuration;
firmware,kernel,fdt,ramdisk,fpga,scriptand each item ofloadablesandsign-imagesmustname an existing image;
image-datamust name an existing imageand the target must not itself have
image-data(no chains).whitespace are flagged with a specific diagnostic and a "did you
mean" hint, instead of being buried under a generic
Unexpected property error.
Commits
Tests
28 unit tests pass. Fixtures cover the happy path plus the most useful
failure modes (missing required props, type-driven requirement gating,
unknown enum values, broken cross-references, malformed property names
and the no-chain rule for
image-data). Hash- and signature-relatedtests are built directly with
libfdtso they exercise the binaryform rather than going through
dtc.Known gaps
Still on the audit list, deferred for follow-up:
dm-veritysubnodes (chapter 5, lines 555-644) underfilesystem-typed images, with seven mandatory properties andthe size/power-of-2 constraints.
compatibleproperty(the spec only enumerates the fpga loading methods explicitly, so
for now the value list is left open).
Test plan
python3 -m fit_validate.validate_testand confirm 28tests pass.
build and confirm the output is sensible.
.uplsuffix; confirmproject,firmwareandrequire-fitare recognisedwithout passing
-u.