]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
bootstd: Avoid freeing a non-allocated buffer
authorSimon Glass <sjg@chromium.org>
Thu, 16 Nov 2023 01:35:23 +0000 (18:35 -0700)
committerTom Rini <trini@konsulko.com>
Fri, 17 Nov 2023 16:58:26 +0000 (11:58 -0500)
EFI applications can be very large and thus used to cause boot failures
when malloc() space was exhausted.

A recent changed fixed this by using the kernel_addr_r environment var
as the address of the buffer. However, it still frees the buffer when
the bootflow is discarded.

Fix this by introducing a flag to indicate whether the buffer was
allocated, or not.

Note that kernel_addr_r is not the last word here. It might be better
to use lmb to place images. But there is a lot of refactoring to do
before we can remove the environment variables. The distro scripts rely
on them so it is safe for bootstd to do so too.

Fixes: 6a8c2f9781c bootstd: Avoid allocating memory for the EFI file
Signed-off-by: Simon Glass <sjg@chromium.org>
Reported by: Simon Glass <sjg@chromium.org>
Reported by: Shantur Rathore <i@shantur.com>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Tested-by: Shantur Rathore <i@shantur.com>
boot/bootflow.c
boot/bootmeth_efi.c
include/bootflow.h

index 6922e7e0c4e753760215f77e101e110c6bad1d31..1ea2966ae9a5b8c56d92a81a399c78b4d0b5e19d 100644 (file)
@@ -467,7 +467,8 @@ void bootflow_free(struct bootflow *bflow)
        free(bflow->name);
        free(bflow->subdir);
        free(bflow->fname);
-       free(bflow->buf);
+       if (!(bflow->flags & BOOTFLOWF_STATIC_BUF))
+               free(bflow->buf);
        free(bflow->os_name);
        free(bflow->fdt_fname);
        free(bflow->bootmeth_priv);
index ae936c8daa1835c7bb59ebfa7699c1112b769a01..9ba7734911e13d1bdd52fbb885a7ef256a3d859d 100644 (file)
@@ -160,6 +160,7 @@ static int efiload_read_file(struct bootflow *bflow, ulong addr)
        if (ret)
                return log_msg_ret("read", ret);
        bflow->buf = map_sysmem(addr, bflow->size);
+       bflow->flags |= BOOTFLOWF_STATIC_BUF;
 
        set_efi_bootdev(desc, bflow);
 
index 44d3741eacae0ea12000ff5e6110068d17bde3d6..fede8f22a2b8caf6eb52331d95be2338dcadfc5b 100644 (file)
@@ -43,9 +43,12 @@ enum bootflow_state_t {
  *     and it is using the prior-stage FDT, which is the U-Boot control FDT.
  *     This is only possible with the EFI bootmeth (distro-efi) and only when
  *     CONFIG_OF_HAS_PRIOR_STAGE is enabled
+ * @BOOTFLOWF_STATIC_BUF: Indicates that @bflow->buf is statically set, rather
+ *     than being allocated by malloc().
  */
 enum bootflow_flags_t {
        BOOTFLOWF_USE_PRIOR_FDT = 1 << 0,
+       BOOTFLOWF_STATIC_BUF    = 1 << 1,
 };
 
 /**
@@ -72,7 +75,7 @@ enum bootflow_flags_t {
  * @fname: Filename of bootflow file (allocated)
  * @logo: Logo to display for this bootflow (BMP format)
  * @logo_size: Size of the logo in bytes
- * @buf: Bootflow file contents (allocated)
+ * @buf: Bootflow file contents (allocated unless @flags & BOOTFLOWF_STATIC_BUF)
  * @size: Size of bootflow file in bytes
  * @err: Error number received (0 if OK)
  * @os_name: Name of the OS / distro being booted, or NULL if not known