[PATCH v1] bootm: bound-check OS index in bootm_os_get_boot_func()
Simon Glass
sjg at chromium.org
Fri Jun 12 20:22:44 CEST 2026
Hi Aristo,
On Sun, 24 May 2026 at 17:11, Aristo Chen <aristo.chen at canonical.com> wrote:
>
> The boot_os[] table in bootm_os.c is a sparse array whose compile-time
> size is set by its largest designated initializer (IH_OS_ELF), giving
> it IH_OS_ELF + 1 entries. The accessor bootm_os_get_boot_func() returns
> boot_os[os] without any bound check, even though the caller in
> bootm_run_states() passes images->os.os straight through. That field is
> populated by image_get_os() from the raw 8-bit ih_os byte of a legacy
> uImage, and by fit_image_get_os() for a FIT, neither of which clamps
> the value against the table size.
>
> An attacker-supplied image whose OS field falls outside the populated
> range therefore drives an out-of-bounds read of boot_os[]. The caller
> only rejects a NULL return, so a non-NULL adjacent global is accepted
> as a valid handler and invoked through the indirect call in
> boot_selected_os(), turning an unsigned image with a malformed header
> into a jump through an attacker-influenced function pointer. FIT
> signature verification covers the os property and mitigates this path
> for signed images, but legacy bootm and unsigned FIT do not.
>
> Reject out-of-range indices in bootm_os_get_boot_func() so the existing
> NULL handling in bootm_run_states() reports an unsupported OS and
> declines to boot the image.
>
> Signed-off-by: Aristo Chen <aristo.chen at canonical.com>
> ---
> boot/bootm_os.c | 2 ++
> 1 file changed, 2 insertions(+)
I would rather put this check earlier and only for legacy images, to
reduce code size. For FIT I believe this cannot happen, right?
>
> diff --git a/boot/bootm_os.c b/boot/bootm_os.c
> index ae20b555f5c..69aa577a2fc 100644
> --- a/boot/bootm_os.c
> +++ b/boot/bootm_os.c
> @@ -599,5 +599,7 @@ int boot_selected_os(int state, struct bootm_info *bmi, boot_os_fn *boot_fn)
>
> boot_os_fn *bootm_os_get_boot_func(int os)
> {
> + if (os < 0 || os >= ARRAY_SIZE(boot_os))
> + return NULL;
> return boot_os[os];
> }
> --
> 2.43.0
>
Regards,
SImon
More information about the U-Boot
mailing list