aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2023-11-15 18:35:23 -0700
committerTom Rini <trini@konsulko.com>2023-11-17 11:58:26 -0500
commit741d1e9d3f368908e3cd1861ddd707e81e1fd576 (patch)
treee47d7a2b4615b494952fc39ce8ad819faf57ebd1
parent169c3cc49e40758956ee6c310f7f59a6443826a1 (diff)
downloadu-boot-741d1e9d3f368908e3cd1861ddd707e81e1fd576.zip
u-boot-741d1e9d3f368908e3cd1861ddd707e81e1fd576.tar.gz
u-boot-741d1e9d3f368908e3cd1861ddd707e81e1fd576.tar.bz2
bootstd: Avoid freeing a non-allocated buffer
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>
-rw-r--r--boot/bootflow.c3
-rw-r--r--boot/bootmeth_efi.c1
-rw-r--r--include/bootflow.h5
3 files changed, 7 insertions, 2 deletions
diff --git a/boot/bootflow.c b/boot/bootflow.c
index 6922e7e..1ea2966 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -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);
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index ae936c8..9ba7734 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -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);
diff --git a/include/bootflow.h b/include/bootflow.h
index 44d3741..fede8f2 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -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