Turn spl_test_fit_external_oversize() into a parameterized helper which builds a FIT with external data, overwrites one property of the image node with a hostile value and checks that spl_load_simple_fit() fails with the expected error.
This is in preparation for adding tests for the remaining external-data properties. No functional change. Signed-off-by: Anton Ivanov <[email protected]> --- test/image/spl_load.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/test/image/spl_load.c b/test/image/spl_load.c index c43c977f784..49bfce15c08 100644 --- a/test/image/spl_load.c +++ b/test/image/spl_load.c @@ -368,52 +368,62 @@ 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. + * Build a FIT with external data, overwrite one property of the image node + * with a hostile value and check that loading fails with the expected error. + * The external-data properties are excluded from the configuration signature, + * so load_simple_fit() must reject values that would wrap its offset/size + * arithmetic rather than read from a bogus location. */ -static int spl_test_fit_external_oversize(struct unit_test_state *uts) +static int check_fit_ext_prop(struct unit_test_state *uts, const char *prop, + u32 value, uint bl_len, spl_load_reader h_read, + ulong fit_offset, int expected) { size_t img_size, img_data, data_size = SPL_TEST_DATA_SIZE; struct spl_image_info info_write = { - .name = "oversize", + .name = "ext-prop", .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"); + generate_data(img + img_data, data_size, "ext-prop"); 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)); + ut_assertok(fdt_setprop_inplace_u32(img, node, prop, value)); - spl_load_init(&load, spl_test_read, img, 1); - ut_asserteq(-EFBIG, spl_load_simple_fit(&info_read, &load, 0, img)); + spl_load_init(&load, h_read, img, bl_len); + ut_asserteq(expected, + spl_load_simple_fit(&info_read, &load, fit_offset, img)); free(img); return 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) +{ + if (!image_supported(FIT_EXTERNAL)) + return -EAGAIN; + + return check_fit_ext_prop(uts, FIT_DATA_SIZE_PROP, 0x40000000, 1, + spl_test_read, 0, -EFBIG); +} SPL_TEST(spl_test_fit_external_oversize, 0); /* -- 2.51.0
