Merge patch series "mkimage: validate image references in FIT configurations"
Aristo Chen <jj251510319013@gmail.com> says: This series introduces a validation step in mkimage to ensure that all image names referenced under the /configurations node of a FIT source (ITS) are actually defined under the /images node. ### Motivation When using mkimage to build FIT images, it's easy to mistakenly reference nonexistent image nodes in configurations (e.g., referencing a missing `fdt` or `firmware` node). Such issues are often not caught until runtime in U-Boot. This series aims to catch these errors early during FIT image creation by validating the configuration references in mkimage itself. Link: https://lore.kernel.org/r/20250610074121.8308-1-aristo.chen@canonical.com
This commit is contained in:
@@ -400,11 +400,105 @@
|
||||
};
|
||||
|
||||
&binman {
|
||||
tifsstub-hs {
|
||||
filename = "tifsstub.bin_hs";
|
||||
ti-secure-rom {
|
||||
content = <&tifsstub_hs_cert>;
|
||||
core = "secure";
|
||||
load = <0x40000>;
|
||||
sw-rev = <CONFIG_K3_X509_SWRV>;
|
||||
keyfile = "custMpk.pem";
|
||||
countersign;
|
||||
tifsstub;
|
||||
};
|
||||
tifsstub_hs_cert: tifsstub-hs-cert.bin {
|
||||
filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin";
|
||||
type = "blob-ext";
|
||||
optional;
|
||||
};
|
||||
tifsstub_hs_enc: tifsstub-hs-enc.bin {
|
||||
filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin";
|
||||
type = "blob-ext";
|
||||
optional;
|
||||
};
|
||||
};
|
||||
|
||||
tifsstub-fs {
|
||||
filename = "tifsstub.bin_fs";
|
||||
tifsstub_fs_cert: tifsstub-fs-cert.bin {
|
||||
filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin";
|
||||
type = "blob-ext";
|
||||
optional;
|
||||
};
|
||||
tifsstub_fs_enc: tifsstub-fs-enc.bin {
|
||||
filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin";
|
||||
type = "blob-ext";
|
||||
optional;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
tifsstub-gp {
|
||||
filename = "tifsstub.bin_gp";
|
||||
ti-secure-rom {
|
||||
content = <&tifsstub_gp>;
|
||||
core = "secure";
|
||||
load = <0x60000>;
|
||||
sw-rev = <CONFIG_K3_X509_SWRV>;
|
||||
keyfile = "ti-degenerate-key.pem";
|
||||
tifsstub;
|
||||
};
|
||||
tifsstub_gp: tifsstub-gp.bin {
|
||||
filename = "ti-sysfw/ti-fs-stub-firmware-am62x-gp.bin";
|
||||
type = "blob-ext";
|
||||
optional;
|
||||
};
|
||||
};
|
||||
|
||||
ti-spl_unsigned {
|
||||
insert-template = <&ti_spl_unsigned_template>;
|
||||
|
||||
fit {
|
||||
images {
|
||||
tifsstub-hs {
|
||||
description = "TIFSSTUB";
|
||||
type = "firmware";
|
||||
arch = "arm32";
|
||||
compression = "none";
|
||||
os = "tifsstub-hs";
|
||||
load = <0x9dc00000>;
|
||||
entry = <0x9dc00000>;
|
||||
blob-ext {
|
||||
filename = "tifsstub.bin_hs";
|
||||
};
|
||||
};
|
||||
|
||||
tifsstub-fs {
|
||||
description = "TIFSSTUB";
|
||||
type = "firmware";
|
||||
arch = "arm32";
|
||||
compression = "none";
|
||||
os = "tifsstub-fs";
|
||||
load = <0x9dc00000>;
|
||||
entry = <0x9dc00000>;
|
||||
blob-ext {
|
||||
filename = "tifsstub.bin_fs";
|
||||
};
|
||||
};
|
||||
|
||||
tifsstub-gp {
|
||||
description = "TIFSSTUB";
|
||||
type = "firmware";
|
||||
arch = "arm32";
|
||||
compression = "none";
|
||||
os = "tifsstub-gp";
|
||||
load = <0x9dc00000>;
|
||||
entry = <0x9dc00000>;
|
||||
blob-ext {
|
||||
filename = "tifsstub.bin_gp";
|
||||
};
|
||||
};
|
||||
|
||||
dm {
|
||||
ti-dm {
|
||||
filename = "ti-dm/am62xx/ipc_echo_testb_mcu1_0_release_strip.xer5f";
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2025
|
||||
#
|
||||
# Test that mkimage validates image references in configurations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import pytest
|
||||
import fit_util
|
||||
|
||||
@pytest.mark.boardspec('sandbox')
|
||||
@pytest.mark.requiredtool('dtc')
|
||||
def test_fit_invalid_image_reference(ubman):
|
||||
"""Test that mkimage fails when configuration references a missing image"""
|
||||
|
||||
its_fname = fit_util.make_fname(ubman, "invalid.its")
|
||||
itb_fname = fit_util.make_fname(ubman, "invalid.itb")
|
||||
kernel = fit_util.make_kernel(ubman, 'kernel.bin', 'kernel')
|
||||
|
||||
# Write ITS with an invalid reference to a nonexistent image
|
||||
its_text = '''
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
images {
|
||||
kernel@1 {
|
||||
description = "Test Kernel";
|
||||
data = /incbin/("kernel.bin");
|
||||
type = "kernel";
|
||||
arch = "sandbox";
|
||||
os = "linux";
|
||||
compression = "none";
|
||||
load = <0x40000>;
|
||||
entry = <0x40000>;
|
||||
};
|
||||
};
|
||||
|
||||
configurations {
|
||||
default = "conf@1";
|
||||
conf@1 {
|
||||
kernel = "kernel@1";
|
||||
fdt = "notexist";
|
||||
};
|
||||
};
|
||||
};
|
||||
'''
|
||||
|
||||
with open(its_fname, 'w') as f:
|
||||
f.write(its_text)
|
||||
|
||||
mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage')
|
||||
cmd = [mkimage, '-f', its_fname, itb_fname]
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
assert result.returncode != 0, "mkimage should fail due to missing image reference"
|
||||
assert "references undefined image 'notexist'" in result.stderr
|
||||
|
||||
@@ -15,6 +15,20 @@
|
||||
fit,fdt-list = "of-list";
|
||||
|
||||
images {
|
||||
atf {
|
||||
description = "atf firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
uboot {
|
||||
description = "U-Boot firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
kernel {
|
||||
description = "Vanilla Linux kernel";
|
||||
type = "kernel";
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
test {
|
||||
kernel {
|
||||
description = "Something using a bintool";
|
||||
type = "kernel";
|
||||
arch = "arm";
|
||||
|
||||
@@ -15,6 +15,20 @@
|
||||
fit,fdt-list = "of-list";
|
||||
|
||||
images {
|
||||
atf {
|
||||
description = "atf firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
uboot {
|
||||
description = "U-Boot firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
kernel {
|
||||
description = "Vanilla Linux kernel";
|
||||
type = "kernel";
|
||||
|
||||
@@ -15,6 +15,20 @@
|
||||
fit,fdt-list-val = "test-fdt1", "test-fdt2";
|
||||
|
||||
images {
|
||||
atf {
|
||||
description = "atf firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
uboot {
|
||||
description = "U-Boot firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
kernel {
|
||||
description = "Vanilla Linux kernel";
|
||||
type = "kernel";
|
||||
|
||||
@@ -15,6 +15,20 @@
|
||||
fit,fdt-list-dir = "fdts";
|
||||
|
||||
images {
|
||||
atf {
|
||||
description = "atf firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
uboot {
|
||||
description = "U-Boot firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
kernel {
|
||||
description = "Vanilla Linux kernel";
|
||||
type = "kernel";
|
||||
|
||||
@@ -15,6 +15,20 @@
|
||||
fit,fdt-list = "of-list";
|
||||
|
||||
images {
|
||||
atf {
|
||||
description = "atf firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
uboot {
|
||||
description = "U-Boot firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
kernel {
|
||||
description = "Vanilla Linux kernel";
|
||||
type = "kernel";
|
||||
|
||||
@@ -15,6 +15,20 @@
|
||||
fit,fdt-list = "of-list";
|
||||
|
||||
images {
|
||||
atf {
|
||||
description = "atf firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
uboot {
|
||||
description = "U-Boot firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
kernel {
|
||||
description = "Vanilla Linux kernel";
|
||||
type = "kernel";
|
||||
|
||||
@@ -15,6 +15,20 @@
|
||||
fit,fdt-list = "of-list";
|
||||
|
||||
images {
|
||||
atf {
|
||||
description = "atf firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
uboot {
|
||||
description = "U-Boot firmware";
|
||||
type = "firmware";
|
||||
compression = "none";
|
||||
load = <00000000>;
|
||||
entry = <00000000>;
|
||||
};
|
||||
kernel {
|
||||
description = "Vanilla Linux kernel";
|
||||
type = "kernel";
|
||||
|
||||
+40
-2
@@ -627,6 +627,7 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
|
||||
struct stat sbuf;
|
||||
int ret;
|
||||
int images;
|
||||
int confs;
|
||||
int node;
|
||||
|
||||
fd = mmap_fdt(params->cmdname, fname, 0, &old_fdt, &sbuf, false, false);
|
||||
@@ -695,6 +696,43 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
|
||||
}
|
||||
}
|
||||
|
||||
confs = fdt_path_offset(fdt, FIT_CONFS_PATH);
|
||||
static const char * const props[] = { FIT_KERNEL_PROP,
|
||||
FIT_RAMDISK_PROP,
|
||||
FIT_FDT_PROP,
|
||||
FIT_LOADABLE_PROP,
|
||||
FIT_FPGA_PROP,
|
||||
FIT_FIRMWARE_PROP,
|
||||
FIT_SCRIPT_PROP};
|
||||
|
||||
fdt_for_each_subnode(node, fdt, confs) {
|
||||
const char *conf_name = fdt_get_name(fdt, node, NULL);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(props); i++) {
|
||||
int count = fdt_stringlist_count(fdt, node, props[i]);
|
||||
|
||||
if (count < 0)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < count; j++) {
|
||||
const char *img_name =
|
||||
fdt_stringlist_get(fdt, node, props[i], j, NULL);
|
||||
if (!img_name || !*img_name)
|
||||
continue;
|
||||
|
||||
int img = fdt_subnode_offset(fdt, images, img_name);
|
||||
|
||||
if (img < 0) {
|
||||
fprintf(stderr,
|
||||
"Error: configuration '%s' references undefined image '%s' in property '%s'\n",
|
||||
conf_name, img_name, props[i]);
|
||||
ret = FDT_ERR_NOTFOUND;
|
||||
goto err_munmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
munmap(old_fdt, sbuf.st_size);
|
||||
|
||||
/* Close the old fd so we can re-use it. */
|
||||
@@ -750,7 +788,7 @@ static int fit_handle_file(struct image_tool_params *params)
|
||||
char bakfile[MKIMAGE_MAX_TMPFILE_LEN + 4] = {0};
|
||||
char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN];
|
||||
size_t size_inc;
|
||||
int ret;
|
||||
int ret = EXIT_FAILURE;
|
||||
|
||||
/* Flattened Image Tree (FIT) format handling */
|
||||
debug ("FIT format handling\n");
|
||||
@@ -854,7 +892,7 @@ static int fit_handle_file(struct image_tool_params *params)
|
||||
err_system:
|
||||
unlink(tmpfile);
|
||||
unlink(bakfile);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+6
-1
@@ -519,8 +519,13 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
retval = tparams->fflag_handle(¶ms);
|
||||
|
||||
if (retval != EXIT_SUCCESS)
|
||||
if (retval != EXIT_SUCCESS) {
|
||||
if (retval == FDT_ERR_NOTFOUND) {
|
||||
// Already printed error, exit cleanly
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
usage("Bad parameters for FIT image type");
|
||||
}
|
||||
}
|
||||
|
||||
if (params.lflag || params.fflag) {
|
||||
|
||||
Reference in New Issue
Block a user