bootm: bound-check OS index in bootm_os_get_boot_func()
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@canonical.com>
This commit is contained in:
@@ -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];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user