summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAristo Chen <[email protected]>2026-07-08 10:34:49 +0000
committerTom Rini <[email protected]>2026-07-21 13:50:54 -0600
commit85667122fb5fa215315a633335efc27ecd195b21 (patch)
tree6b36c7ec817c79a4d54ac9cefe96f8eaf77e33b5
parent8f71d7170f5c3abadee45683e35ae6d925b6d417 (diff)
test: spl: check load_simple_fit() rejects an oversized data-size
Add a regression test that builds a FIT with external data, inflates the data-size property far beyond the image and any plausible load region, and confirms that spl_load_simple_fit() returns -EFBIG instead of reading the declared size off the device. Without the bounds check in load_simple_fit() this test overruns memory and crashes; with it the load is rejected cleanly. Signed-off-by: Aristo Chen <[email protected]> Reviewed-by: Simon Glass <[email protected]>
-rw-r--r--test/image/spl_load.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/test/image/spl_load.c b/test/image/spl_load.c
index 3b6206955d3..c43c977f784 100644
--- a/test/image/spl_load.c
+++ b/test/image/spl_load.c
@@ -368,6 +368,55 @@ SPL_IMG_TEST(spl_test_image, FIT_INTERNAL, 0);
SPL_IMG_TEST(spl_test_image, FIT_EXTERNAL, 0);
/*
+ * A FIT image's data-size property is not covered by the configuration
+ * signature, so it is untrusted input. load_simple_fit() must reject a
+ * data-size larger than the destination rather than overrun it, because the
+ * device read happens before the image hash is verified.
+ */
+static int spl_test_fit_external_oversize(struct unit_test_state *uts)
+{
+ size_t img_size, img_data, data_size = SPL_TEST_DATA_SIZE;
+ struct spl_image_info info_write = {
+ .name = "oversize",
+ .size = data_size,
+ }, info_read = { };
+ struct spl_load_info load;
+ void *img;
+ int node;
+
+ if (!image_supported(FIT_EXTERNAL))
+ return -EAGAIN;
+
+ img_size = create_image(NULL, FIT_EXTERNAL, &info_write, &img_data);
+ ut_assert(img_size);
+ img = calloc(img_size, 1);
+ ut_assertnonnull(img);
+
+ generate_data(img + img_data, data_size, "oversize");
+ ut_asserteq(img_size, create_image(img, FIT_EXTERNAL, &info_write,
+ NULL));
+
+ /*
+ * Inflate data-size far beyond the image buffer and any plausible
+ * load region. Without a bounds check, load_simple_fit() reads this
+ * many bytes off the "device" before the hash is checked.
+ */
+ node = fdt_path_offset(img, FIT_IMAGES_PATH);
+ ut_assert(node >= 0);
+ node = fdt_first_subnode(img, node);
+ ut_assert(node >= 0);
+ ut_assertok(fdt_setprop_inplace_u32(img, node, FIT_DATA_SIZE_PROP,
+ 0x40000000));
+
+ spl_load_init(&load, spl_test_read, img, 1);
+ ut_asserteq(-EFBIG, spl_load_simple_fit(&info_read, &load, 0, img));
+
+ free(img);
+ return 0;
+}
+SPL_TEST(spl_test_fit_external_oversize, 0);
+
+/*
* LZMA is too complex to generate on the fly, so let's use some data I put in
* the oven^H^H^H^H compressed earlier
*/