[PATCH 09/11] boot: fit: share the external-data offset calculation
Daniel Golle
daniel at makrotopia.org
Wed Oct 14 01:40:12 PDT 2026
fit_image_load_storage() repeats the data-position / data-offset /
totalsize-alignment sequence that fit_image_get_data() performs, and
writes the result through an int pointer where the getters expect a u32.
The copy also omits the range check on the sum, so an offset that the
embedded path rejects is accepted here.
Extract fit_image_ext_data_offset() and call it from both. The storage
path gains the range check and both agree on one expression for the
alignment.
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
boot/image-fit.c | 82 ++++++++++++++++++++++++++++++------------------
1 file changed, 51 insertions(+), 31 deletions(-)
diff --git a/boot/image-fit.c b/boot/image-fit.c
index 6ab6c6c7da9..f02ac58d733 100644
--- a/boot/image-fit.c
+++ b/boot/image-fit.c
@@ -1056,6 +1056,47 @@ int fit_image_get_data_size_unciphered(const void *fit, int noffset,
return 0;
}
+/**
+ * fit_image_ext_data_offset - locate a sub-image's external data
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @offsetp: holds the data offset from the start of the FIT, on success
+ *
+ * returns:
+ * 0, if the sub-image has external data
+ * -ENOENT, if its data is embedded in the FIT
+ * -EINVAL, if the recorded offset is out of range
+ */
+static int fit_image_ext_data_offset(const void *fit, int noffset, u32 *offsetp)
+{
+ size_t fdt_total_size_aligned;
+ u32 offset;
+
+ if (!fit_image_get_data_position(fit, noffset, &offset)) {
+ *offsetp = offset;
+
+ return 0;
+ }
+
+ if (fit_image_get_data_offset(fit, noffset, &offset))
+ return -ENOENT;
+
+ /*
+ * data-offset counts from the end of the FDT, so that is the base for
+ * every image; the sum has to stay within a u32.
+ */
+ fdt_total_size_aligned = ALIGN(fdt_totalsize(fit), 4);
+ if (fdt_total_size_aligned > UINT32_MAX - offset) {
+ printf("Invalid external data offset: %u\n", offset);
+
+ return -EINVAL;
+ }
+
+ *offsetp = offset + fdt_total_size_aligned;
+
+ return 0;
+}
+
/**
* fit_image_get_data - get data and its size including
* both embedded and external data
@@ -1077,29 +1118,14 @@ int fit_image_get_data(const void *fit, int noffset, const void **data,
{
bool external_data = false;
int ret;
- size_t fdt_total_size_aligned;
u32 offset;
u32 len;
uintptr_t max_offset;
- if (!fit_image_get_data_position(fit, noffset, &offset)) {
- external_data = true;
- } else if (!fit_image_get_data_offset(fit, noffset, &offset)) {
- /*
- * For FIT with external data, figure out where
- * the external images start. This is the base
- * for the data-offset properties in each image.
- */
- fdt_total_size_aligned = ((fdt_totalsize(fit) + 3) & ~3);
- /* The resulting offset cannot exceed UINT32_MAX */
- if (fdt_total_size_aligned > UINT32_MAX - offset) {
- printf("Invalid external data offset: %u\n", offset);
- return -EINVAL;
- }
- offset += fdt_total_size_aligned;
-
- external_data = true;
- }
+ ret = fit_image_ext_data_offset(fit, noffset, &offset);
+ if (ret && ret != -ENOENT)
+ return ret;
+ external_data = !ret;
if (external_data) {
debug("External Data\n");
@@ -2185,12 +2211,12 @@ static int fit_image_load_storage(struct bootm_headers *images, const void *fit,
int noffset, enum fit_load_op load_op,
ulong *datap, ulong *lenp, bool *early)
{
- int data_off = 0, data_sz = 0;
- bool external = false;
+ u32 data_off = 0, data_sz = 0;
ulong img_load;
u8 img_comp = IH_COMP_NONE;
void *mapped;
void *dst;
+ int ret;
if (CONFIG_IS_ENABLED(FIT_VERITY)) {
u8 img_type;
@@ -2207,19 +2233,13 @@ static int fit_image_load_storage(struct bootm_headers *images, const void *fit,
}
}
- if (!fit_image_get_data_position(fit, noffset, &data_off)) {
- external = true;
- } else if (!fit_image_get_data_offset(fit, noffset, &data_off)) {
- external = true;
- data_off += ALIGN(fdt_totalsize(fit), 4);
- }
+ ret = fit_image_ext_data_offset(fit, noffset, &data_off);
+ if (ret)
+ return ret == -ENOENT ? 0 : ret;
- if (!external || fit_image_get_data_size(fit, noffset, &data_sz))
+ if (fit_image_get_data_size(fit, noffset, &data_sz))
return 0;
- if (data_off < 0 || data_sz < 0)
- return -EINVAL;
-
fit_image_get_comp(fit, noffset, &img_comp);
if (img_comp == IH_COMP_NONE && load_op != FIT_LOAD_IGNORED &&
--
2.56.0
More information about the openwrt-devel
mailing list