[PATCH v1 1/2] bootm: fix overflow of the noload kernel decompression buffer

Aristo Chen aristo.chen at canonical.com
Wed May 27 11:35:03 CEST 2026


Hi Simon,

On Wed, May 27, 2026 at 12:59 PM Simon Glass <sjg at chromium.org> wrote:
>
> Hi Aristo,
>
> On 2026-05-20T04:45:49, 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.
> >
> > Fixes: 69544c4fd8b1 ("bootm: Support kernel_noload with compression")
> > Signed-off-by: Aristo Chen <aristo.chen at canonical.com>
> >
> > boot/bootm.c | 11 ++++++-----
> >  1 file changed, 6 insertions(+), 5 deletions(-)
>
> > diff --git a/boot/bootm.c b/boot/bootm.c
> > @@ -635,17 +636,17 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
> >       load_buf = map_sysmem(load, 0);
> >       image_buf = map_sysmem(os.image_start, image_len);
> >       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);
>
> handle_decomp_error() prints
>
>     Image too large: increase CONFIG_SYS_BOOTM_LEN
>
> when uncomp_size >= buf_size, which is the path the new test
> exercises. In the noload case that advice is misleading - the limit is
> the per-image ALIGN(image_len * 4, SZ_1M) buffer, not
> CONFIG_SYS_BOOTM_LEN, and bumping CONFIG_SYS_BOOTM_LEN will not help.
>
> Worth either tweaking the message to mention the 4x noload buffer, or
> printing a separate note from bootm_load_os() when decomp_len !=
> CONFIG_SYS_BOOTM_LEN. What do you think?

I will prepare a v2 to tweak the message

>
> > diff --git a/boot/bootm.c b/boot/bootm.c
> > @@ -623,11 +624,11 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
> >        * Use an alignment of 2MB since this might help arm64
> >        */
> >       if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE) {
> > -             ulong req_size = ALIGN(image_len * 4, SZ_1M);
> >               phys_addr_t addr;
> >
> > +             decomp_len = ALIGN(image_len * 4, SZ_1M);
>
> It might be worth updating image_decomp() to take a ulong size, since
> now a read per-image size is flowing through (perhaps a follow-up?).

I've written it down in my notes; I will see how to tackle this with a
follow-up patch set

>
> Reviewed-by: Simon Glass <sjg at chromium.org>
>
> Regards,
> Simon

Best regards,
Aristo


More information about the U-Boot mailing list