summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-09-04 12:22:49 -0600
committerTom Rini <[email protected]>2026-09-04 16:55:10 -0600
commit5534f2c742916efabff3e1888912dafc570f20f2 (patch)
tree1ad0e57528769aef86a2cb7e3a4297495125d255 /boot
parent7bf077ec5733a230bbce34d8ce324f92d8c46cc1 (diff)
parent3158b844335a4a84a5504a813f2daa6acff5985d (diff)
Merge patch series "fit: Harden handling of external-data properties"
Anton Ivanov <[email protected]> says: The data-offset, data-position and data-size FIT properties are 32-bit unsigned values, but were read through signed int. Also, they are excluded from the configuration signature, so they are attacker controlled. Patch 1 switches the accessors and their callers to u32, removing the ad-hoc handling of "negative" values in U-Boot proper. This transition was discussed and agreed on in [1]. The SPL loader has its own copy of this logic with the same problems and fewer checks. Patch 2 factors out a test helper, patch 3 makes the SPL offset/size arithmetic overflow-safe, and patch 4 adds the addressable-range and FIT_SIGNATURE_MAX_SIZE bounds check that U-Boot proper already performs in fit_image_get_data(). Patches 3 and 4 build on each other and on patch 1, so they are not intended to be cherry-picked individually. [1] https://lore.kernel.org/u-boot/CAPWaX55XWFLcMGRuaUuXXn__MX_UG4J8QTd6rvXZmJ4WSOCy9w@mail.gmail.com/ Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'boot')
-rw-r--r--boot/image-fit.c29
1 files changed, 10 insertions, 19 deletions
diff --git a/boot/image-fit.c b/boot/image-fit.c
index ef90c5abd18..26e9323da06 100644
--- a/boot/image-fit.c
+++ b/boot/image-fit.c
@@ -963,7 +963,7 @@ int fit_image_get_emb_data(const void *fit, int noffset, const void **data,
* 0, on success
* -ENOENT if the property could not be found
*/
-int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset)
+int fit_image_get_data_offset(const void *fit, int noffset, u32 *data_offset)
{
const fdt32_t *val;
@@ -988,7 +988,7 @@ int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset)
* -ENOENT if the property could not be found
*/
int fit_image_get_data_position(const void *fit, int noffset,
- int *data_position)
+ u32 *data_position)
{
const fdt32_t *val;
@@ -1012,7 +1012,7 @@ int fit_image_get_data_position(const void *fit, int noffset,
* 0, on success
* -ENOENT if the property could not be found
*/
-int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
+int fit_image_get_data_size(const void *fit, int noffset, u32 *data_size)
{
const fdt32_t *val;
@@ -1070,18 +1070,13 @@ int fit_image_get_data(const void *fit, int noffset, const void **data,
size_t *size)
{
bool external_data = false;
- int offset;
- int len;
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)) {
- if (offset < 0) {
- printf("Invalid external data position: %d\n", offset);
- return -EINVAL;
- }
-
external_data = true;
} else if (!fit_image_get_data_offset(fit, noffset, &offset)) {
/*
@@ -1090,9 +1085,9 @@ int fit_image_get_data(const void *fit, int noffset, const void **data,
* for the data-offset properties in each image.
*/
fdt_total_size_aligned = ((fdt_totalsize(fit) + 3) & ~3);
- /* The resulting offset cannot exceed INT_MAX */
- if (offset < 0 || fdt_total_size_aligned > INT_MAX - offset) {
- printf("Invalid external data offset: %d\n", offset);
+ /* 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;
@@ -1106,16 +1101,12 @@ int fit_image_get_data(const void *fit, int noffset, const void **data,
max_offset = UINTPTR_MAX - (uintptr_t)fit;
/* Check that external data offset is within the addressable range */
if (offset > max_offset) {
- printf("Invalid external data offset: %d\n", offset);
+ printf("Invalid external data offset: %u\n", offset);
return -EINVAL;
}
ret = fit_image_get_data_size(fit, noffset, &len);
if (!ret) {
- if (len < 0) {
- printf("Invalid external data size: %d\n", len);
- return -EINVAL;
- }
/*
* For non-signed FIT images, we can only check that
* (offset + len) doesn't exceed the addressable range.
@@ -1135,7 +1126,7 @@ int fit_image_get_data(const void *fit, int noffset, const void **data,
len > CONFIG_VAL(FIT_SIGNATURE_MAX_SIZE) - offset
#endif
) {
- printf("FIT external data is out of bounds (offset=%d, size=%d)\n",
+ printf("FIT external data is out of bounds (offset=%u, size=%u)\n",
offset, len);
return -EINVAL;
}