From ca774b94d66332b6bd033369227ac487ad07d5e8 Mon Sep 17 00:00:00 2001 From: Aristo Chen Date: Tue, 26 May 2026 02:09:14 +0000 Subject: fdt_support: bound serialN alias length before copying to stack fdt_fixup_stdout() reads the path stored in /aliases/serialN with fdt_getprop() and then memcpys it into a fixed 256-byte stack buffer. The length returned by libfdt is the raw on-disk property size and is not bounded by any console-path convention, so an oversized property in a malformed or untrusted devicetree overflows the buffer with attacker-controlled length and contents. The "/* long enough */" comment next to tmp[] codifies an unchecked assumption. Reject lengths that exceed sizeof(tmp) with a debug-only message and return -FDT_ERR_NOSPACE. The fixup runs during fdt_chosen() on every booted kernel when CONFIG_OF_STDOUT_VIA_ALIAS is enabled, and when the OS devicetree is not signature-verified the property is reachable from an attacker-influenced blob. Using debug() rather than printf() keeps the rejection text out of production builds so there is no .text or .rodata growth on space-constrained targets. Signed-off-by: Aristo Chen --- boot/fdt_support.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'boot') diff --git a/boot/fdt_support.c b/boot/fdt_support.c index 1c215e548db..bdf651364b4 100644 --- a/boot/fdt_support.c +++ b/boot/fdt_support.c @@ -160,6 +160,12 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff) goto noalias; } + if (len > (int)sizeof(tmp)) { + debug("%s: %s alias path too long (%d bytes)\n", + __func__, sername, len); + return -FDT_ERR_NOSPACE; + } + /* fdt_setprop may break "path" so we copy it to tmp buffer */ memcpy(tmp, path, len); -- cgit v1.3.1 From 84e250c0a85a615620a461e0710bb970801fb276 Mon Sep 17 00:00:00 2001 From: Aristo Chen Date: Tue, 26 May 2026 02:09:15 +0000 Subject: fdt_support: validate dma-ranges length in fdt_get_dma_range 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. Use debug() rather than printf() for the rejection text so that production builds do not pay any .text or .rodata growth for the new diagnostic. Signed-off-by: Aristo Chen --- boot/fdt_support.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'boot') diff --git a/boot/fdt_support.c b/boot/fdt_support.c index bdf651364b4..632d5b380d7 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))) { + debug("%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); -- cgit v1.3.1