fdt_get_dma_range() fetches the dma-ranges property with fdt_getprop() and checks only that the length is non-zero before reading one full entry from it. The entry size depends on na, pna and ns cells returned by count_cells, which come from the parent buses in the devicetree. A dma-ranges property shorter than (na + pna + ns) * sizeof(u32) bytes causes fdt_read_number() and fdt_translate_dma_address() to read past the end of the property within the FDT blob, an out-of-bounds read of attacker-influenced data when the OS devicetree is not signature verified.
Reject the property when its length is smaller than one full entry and return -EINVAL, matching the existing failure paths in this function. Signed-off-by: Aristo Chen <[email protected]> --- boot/fdt_support.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boot/fdt_support.c b/boot/fdt_support.c index 3e9445603ff..c4c2a5d02f6 100644 --- a/boot/fdt_support.c +++ b/boot/fdt_support.c @@ -1633,6 +1633,13 @@ int fdt_get_dma_range(const void *blob, int node, phys_addr_t *cpu, goto out; } + if (len < (int)((na + pna + ns) * sizeof(*ranges))) { + printf("%s: dma-ranges too short for %s\n", __func__, + fdt_get_name(blob, node, NULL)); + ret = -EINVAL; + goto out; + } + *bus = fdt_read_number(ranges, na); *cpu = fdt_translate_dma_address(blob, node, ranges + na); *size = fdt_read_number(ranges + na + pna, ns); -- 2.43.0

