[PATCH v2 1/3] bootm: fix overflow of the noload kernel decompression buffer
Aristo Chen
aristo.chen at canonical.com
Thu Jun 4 05:39:43 CEST 2026
Hi Simon,
On Thu, Jun 4, 2026 at 12:49 AM Simon Glass <sjg at chromium.org> wrote:
>
> Hi Aristo,
>
> On 2026-05-27T15:04:32, Aristo Chen <aristo.chen at canonical.com> wrote:
> > bootm: fix overflow of the noload kernel decompression buffer
> >
> > For a compressed kernel_noload image, bootm_load_os() allocates a
> > decompression buffer sized to ALIGN(image_len * 4, SZ_1M), assuming the
> > kernel compresses by no more than a factor of four. It then passes
> > CONFIG_SYS_BOOTM_LEN, rather than the size of that buffer, to
> > image_decomp() as the output limit. The decompressors honour the limit
> > they are given, so a kernel that decompresses to more than four times
> > its compressed size is written past the end of the allocated buffer and
> > corrupts adjacent memory.
> >
> > Pass the allocation size to image_decomp() and handle_decomp_error() so
> > decompression stops at the buffer boundary and fails cleanly when the
> > image is too large, instead of overflowing. The regular non-noload
> > paths are unchanged and continue to use CONFIG_SYS_BOOTM_LEN. When the
> > failure is triggered by the smaller per-image buffer, print a note so
> > that handle_decomp_error()'s generic advice to increase
> > CONFIG_SYS_BOOTM_LEN does not mislead the reader.
> >
> > Fixes: 69544c4fd8b1 ("bootm: Support kernel_noload with compression")
> > [...]
> >
> > boot/bootm.c | 14 +++++++++-----
> > 1 file changed, 9 insertions(+), 5 deletions(-)
>
> > diff --git a/boot/bootm.c b/boot/bootm.c
> > @@ -635,17 +636,20 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
> > err = image_decomp(os.comp, load, os.image_start, os.type,
> > load_buf, image_buf, image_len,
> > - CONFIG_SYS_BOOTM_LEN, &load_end);
> > + decomp_len, &load_end);
> > if (err) {
> > err = handle_decomp_error(os.comp, load_end - load,
> > - CONFIG_SYS_BOOTM_LEN, err);
> > + decomp_len, err);
> > + if (decomp_len != CONFIG_SYS_BOOTM_LEN)
> > + printf("Note: noload decompression buffer is %#lx bytes (not CONFIG_SYS_BOOTM_LEN)\n",
> > + decomp_len);
>
> Reviewed-by: Simon Glass <sjg at chromium.org>
>
> The note is printed after handle_decomp_error() has already produced:
>
> Image too large: increase CONFIG_SYS_BOOTM_LEN
> Must RESET board to recover
>
> So I think this is worth a follow-up, too...see also below:
Noted, I will find time to see how to fix this
>
> Using decomp_len != CONFIG_SYS_BOOTM_LEN as the gate is
> indirect - it relies on the alignment never coincidentally matching
> the global limit. The condition you actually want is the one that
> allocated the per-image buffer (IH_TYPE_KERNEL_NOLOAD and os.comp !=
> IH_COMP_NONE), so testing that directly (or a bool set inside the
> allocation block) reads more obviously and stays correct regardless
> of how CONFIG_SYS_BOOTM_LEN is configured.
>
> The cleaner fix is to teach handle_decomp_error() itself about
> the noload buffer (e.g. an extra flag or a separate label for the
> limit), so the 'Image too large: increase CONFIG_SYS_BOOTM_LEN' line
> never gets printed when the noload buffer is the true bound. The
> trailing 'Note:' is essentially patching over a message
> handle_decomp_error() should not have emitted. What do you think?
>
> Regards,
> Simon
Regards,
Aristo
More information about the U-Boot
mailing list