From 666929e311190b4df0b70d1d8e46c802cba7af97 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 28 Mar 2025 14:10:55 +0000 Subject: [PATCH] [efi] Create a copy of the system flattened device tree, if present EFI configuration tables may be freed at any time, and there is no way to be notified when the table becomes invalidated. Create a copy of the system flattened device tree (if present), so that we do not risk being left with an invalid pointer. Signed-off-by: Michael Brown --- src/core/fdt.c | 3 +-- src/include/ipxe/fdt.h | 6 +++--- src/interface/efi/efi_fdt.c | 11 +++++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/core/fdt.c b/src/core/fdt.c index 9c2880c84..4fd2b76bf 100644 --- a/src/core/fdt.c +++ b/src/core/fdt.c @@ -456,8 +456,7 @@ int fdt_mac ( struct fdt *fdt, unsigned int offset, * @v max_len Maximum device tree length * @ret rc Return status code */ -int fdt_parse ( struct fdt *fdt, const struct fdt_header *hdr, - size_t max_len ) { +int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr, size_t max_len ) { const uint8_t *end; /* Sanity check */ diff --git a/src/include/ipxe/fdt.h b/src/include/ipxe/fdt.h index 70dc01790..2799e0d07 100644 --- a/src/include/ipxe/fdt.h +++ b/src/include/ipxe/fdt.h @@ -78,9 +78,9 @@ struct fdt { /** Tree data */ union { /** Tree header */ - const struct fdt_header *hdr; + struct fdt_header *hdr; /** Raw data */ - const void *raw; + void *raw; }; /** Length of tree */ size_t len; @@ -107,7 +107,7 @@ extern int fdt_u64 ( struct fdt *fdt, unsigned int offset, const char *name, uint64_t *value ); extern int fdt_mac ( struct fdt *fdt, unsigned int offset, struct net_device *netdev ); -extern int fdt_parse ( struct fdt *fdt, const struct fdt_header *hdr, +extern int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr, size_t max_len ); #endif /* _IPXE_FDT_H */ diff --git a/src/interface/efi/efi_fdt.c b/src/interface/efi/efi_fdt.c index e207f7e6d..71b788ae7 100644 --- a/src/interface/efi/efi_fdt.c +++ b/src/interface/efi/efi_fdt.c @@ -44,6 +44,8 @@ EFI_USE_TABLE ( FDT_TABLE, &efi_fdt, 0 ); * */ static void efi_fdt_init ( void ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + EFI_STATUS efirc; int rc; /* Do nothing if no configuration table is present */ @@ -59,6 +61,15 @@ static void efi_fdt_init ( void ) { strerror ( rc ) ); return; } + + /* Create copy, since table may be removed at any time */ + if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, sysfdt.len, + &sysfdt.raw ) ) != 0 ) { + DBGC ( &efi_fdt, "EFIFDT could not create copy\n" ); + sysfdt.len = 0; + return; + } + memcpy ( sysfdt.raw, efi_fdt, sysfdt.len ); } /** EFI Flattened Device Tree initialisation function */