From: Lennart Poettering Date: Wed, 26 Jun 2024 09:18:51 +0000 (+0200) Subject: stub: add DevicetreeAddon structure X-Git-Tag: v257-rc1~1041^2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e2ed6c78fd22f683e3360f7b58c424f93d9f6e1;p=thirdparty%2Fsystemd.git stub: add DevicetreeAddon structure Instead of keeping three parallel arrays of dt base, dt size and dt filename, just introduce a proper structure and use an array of that, greatly simplifying DT handling. --- diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 2bea86ff99a..363184ef10e 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -312,100 +312,90 @@ static void cmdline_append_and_measure_addons( *cmdline_append = xasprintf("%ls%ls%ls", strempty(tmp), isempty(tmp) ? u"" : u" ", merged); } -static void dtb_install_addons( +typedef struct DevicetreeAddon { + char16_t *filename; + struct iovec blob; +} DevicetreeAddon; + +static void devicetree_addon_done(DevicetreeAddon *a) { + assert(a); + + a->filename = mfree(a->filename); + iovec_done(&a->blob); +} + +static void devicetree_addon_free_many(DevicetreeAddon *a, size_t n) { + assert(a || n == 0); + + FOREACH_ARRAY(i, a, n) + devicetree_addon_done(i); + + free(a); +} + +static void install_addon_devicetrees( struct devicetree_state *dt_state, - void **dt_bases, - size_t *dt_sizes, - char16_t **dt_filenames, - size_t n_dts, + DevicetreeAddon *addons, + size_t n_addons, int *ret_parameters_measured) { int parameters_measured = -1; EFI_STATUS err; assert(dt_state); - assert(n_dts == 0 || (dt_bases && dt_sizes && dt_filenames)); + assert(addons || n_addons == 0); assert(ret_parameters_measured); - for (size_t i = 0; i < n_dts; ++i) { - err = devicetree_install_from_memory(dt_state, dt_bases[i], dt_sizes[i]); - if (err != EFI_SUCCESS) + FOREACH_ARRAY(a, addons, n_addons) { + err = devicetree_install_from_memory(dt_state, a->blob.iov_base, a->blob.iov_len); + if (err != EFI_SUCCESS) { log_error_status(err, "Error loading addon devicetree, ignoring: %m"); - else { - bool m = false; + continue; + } - err = tpm_log_tagged_event( + bool m = false; + err = tpm_log_tagged_event( + TPM2_PCR_KERNEL_CONFIG, + POINTER_TO_PHYSICAL_ADDRESS(a->blob.iov_base), + a->blob.iov_len, + DEVICETREE_ADDON_EVENT_TAG_ID, + a->filename, + &m); + if (err != EFI_SUCCESS) + return (void) log_error_status( + err, + "Unable to extend PCR %i with DTB addon '%ls': %m", TPM2_PCR_KERNEL_CONFIG, - POINTER_TO_PHYSICAL_ADDRESS(dt_bases[i]), - dt_sizes[i], - DEVICETREE_ADDON_EVENT_TAG_ID, - dt_filenames[i], - &m); - if (err != EFI_SUCCESS) - return (void) log_error_status( - err, - "Unable to add measurement of DTB addon #%zu to PCR %i: %m", - i, - TPM2_PCR_KERNEL_CONFIG); - - combine_measured_flag(¶meters_measured, m); - } + a->filename); + + combine_measured_flag(¶meters_measured, m); } *ret_parameters_measured = parameters_measured; } -static void dt_bases_free(void **dt_bases, size_t n_dt) { - assert(dt_bases || n_dt == 0); - - for (size_t i = 0; i < n_dt; ++i) - free(dt_bases[i]); - - free(dt_bases); -} - -static void dt_filenames_free(char16_t **dt_filenames, size_t n_dt) { - assert(dt_filenames || n_dt == 0); - - for (size_t i = 0; i < n_dt; ++i) - free(dt_filenames[i]); - - free(dt_filenames); -} - static EFI_STATUS load_addons( EFI_HANDLE stub_image, EFI_LOADED_IMAGE_PROTOCOL *loaded_image, const char16_t *prefix, const char *uname, char16_t **ret_cmdline, - void ***ret_dt_bases, - size_t **ret_dt_sizes, - char16_t ***ret_dt_filenames, - size_t *ret_n_dt) { + DevicetreeAddon **ret_devicetree_addons, + size_t *ret_n_devicetree_addons) { - _cleanup_free_ size_t *dt_sizes = NULL; _cleanup_(strv_freep) char16_t **items = NULL; _cleanup_(file_closep) EFI_FILE *root = NULL; _cleanup_free_ char16_t *cmdline = NULL; - size_t n_items = 0, n_allocated = 0, n_dt = 0; - char16_t **dt_filenames = NULL; - void **dt_bases = NULL; + size_t n_items = 0, n_allocated = 0; EFI_STATUS err; assert(stub_image); assert(loaded_image); assert(prefix); - assert(!!ret_dt_bases == !!ret_dt_sizes); - assert(!!ret_dt_bases == !!ret_n_dt); - assert(!!ret_dt_filenames == !!ret_n_dt); if (!loaded_image->DeviceHandle) return EFI_SUCCESS; - CLEANUP_ARRAY(dt_bases, n_dt, dt_bases_free); - CLEANUP_ARRAY(dt_filenames, n_dt, dt_filenames_free); - err = open_volume(loaded_image->DeviceHandle, &root); if (err == EFI_UNSUPPORTED) /* Error will be unsupported if the bootloader doesn't implement the file system protocol on @@ -425,6 +415,10 @@ static EFI_STATUS load_addons( * are not dependent on read order) */ sort_pointer_array((void**) items, n_items, (compare_pointer_func_t) strcmp16); + DevicetreeAddon *dt_addons = NULL; + size_t n_dt_addons = 0; + CLEANUP_ARRAY(dt_addons, n_dt_addons, devicetree_addon_free_many); + for (size_t i = 0; i < n_items; i++) { PeSectionVector sections[ELEMENTSOF(unified_sections)] = {}; _cleanup_free_ EFI_DEVICE_PATH *addon_path = NULL; @@ -489,36 +483,27 @@ static EFI_STATUS load_addons( cmdline = xasprintf("%ls%ls%ls", strempty(tmp), isempty(tmp) ? u"" : u" ", extra16); } - if (ret_dt_bases && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB)) { - dt_sizes = xrealloc(dt_sizes, - n_dt * sizeof(size_t), - (n_dt + 1) * sizeof(size_t)); - dt_sizes[n_dt] = sections[UNIFIED_SECTION_DTB].size; - - dt_bases = xrealloc(dt_bases, - n_dt * sizeof(void *), - (n_dt + 1) * sizeof(void *)); - dt_bases[n_dt] = xmemdup((uint8_t*)loaded_addon->ImageBase + sections[UNIFIED_SECTION_DTB].memory_offset, - dt_sizes[n_dt]); - - dt_filenames = xrealloc(dt_filenames, - n_dt * sizeof(char16_t *), - (n_dt + 1) * sizeof(char16_t *)); - dt_filenames[n_dt] = xstrdup16(items[i]); - - ++n_dt; + if (ret_devicetree_addons && PE_SECTION_VECTOR_IS_SET(sections + UNIFIED_SECTION_DTB)) { + dt_addons = xrealloc(dt_addons, + n_dt_addons * sizeof(size_t), + (n_dt_addons + 1) * sizeof(size_t)); + + dt_addons[n_dt_addons++] = (DevicetreeAddon) { + .blob = { + .iov_base = xmemdup((const uint8_t*) loaded_addon->ImageBase + sections[UNIFIED_SECTION_DTB].memory_offset, sections[UNIFIED_SECTION_DTB].size), + .iov_len = sections[UNIFIED_SECTION_DTB].size, + }, + .filename = xstrdup16(items[i]), + }; } } - if (ret_cmdline && !isempty(cmdline)) + if (ret_cmdline) *ret_cmdline = TAKE_PTR(cmdline); - - if (ret_n_dt && n_dt > 0) { - *ret_dt_filenames = TAKE_PTR(dt_filenames); - *ret_dt_bases = TAKE_PTR(dt_bases); - *ret_dt_sizes = TAKE_PTR(dt_sizes); - *ret_n_dt = n_dt; - } + if (ret_devicetree_addons) + *ret_devicetree_addons = TAKE_PTR(dt_addons); + if (ret_n_devicetree_addons) + *ret_n_devicetree_addons = n_dt_addons; return EFI_SUCCESS; } @@ -842,10 +827,8 @@ static void install_embedded_devicetree( static EFI_STATUS run(EFI_HANDLE image) { _cleanup_(initrds_free) struct iovec initrds[_INITRD_MAX] = {}; - void **dt_bases_addons_global = NULL, **dt_bases_addons_uki = NULL; - char16_t **dt_filenames_addons_global = NULL, **dt_filenames_addons_uki = NULL; - _cleanup_free_ size_t *dt_sizes_addons_global = NULL, *dt_sizes_addons_uki = NULL; - size_t n_dts_addons_global = 0, n_dts_addons_uki = 0; + DevicetreeAddon *dt_addons_global = NULL, *dt_addons_local = NULL; + size_t n_dt_addons_global = 0, n_dt_addons_local = 0; _cleanup_(devicetree_cleanup) struct devicetree_state dt_state = {}; EFI_LOADED_IMAGE_PROTOCOL *loaded_image; PeSectionVector sections[ELEMENTSOF(unified_sections)] = {}; @@ -868,13 +851,11 @@ static EFI_STATUS run(EFI_HANDLE image) { return log_error_status(err, "Unable to locate embedded .linux section: %m"); } - CLEANUP_ARRAY(dt_bases_addons_global, n_dts_addons_global, dt_bases_free); - CLEANUP_ARRAY(dt_bases_addons_uki, n_dts_addons_uki, dt_bases_free); - CLEANUP_ARRAY(dt_filenames_addons_global, n_dts_addons_global, dt_filenames_free); - CLEANUP_ARRAY(dt_filenames_addons_uki, n_dts_addons_uki, dt_filenames_free); - lookup_uname(loaded_image, sections, &uname); + CLEANUP_ARRAY(dt_addons_global, n_dt_addons_local, devicetree_addon_free_many); + CLEANUP_ARRAY(dt_addons_local, n_dt_addons_local, devicetree_addon_free_many); + /* Now that we have the UKI sections loaded, also load global first and then local (per-UKI) * addons. The data is loaded at once, and then used later. */ err = load_addons( @@ -883,10 +864,8 @@ static EFI_STATUS run(EFI_HANDLE image) { u"\\loader\\addons", uname, &cmdline_addons_global, - &dt_bases_addons_global, - &dt_sizes_addons_global, - &dt_filenames_addons_global, - &n_dts_addons_global); + &dt_addons_global, + &n_dt_addons_global); if (err != EFI_SUCCESS) log_error_status(err, "Error loading global addons, ignoring: %m"); @@ -899,10 +878,8 @@ static EFI_STATUS run(EFI_HANDLE image) { dropin_dir, uname, &cmdline_addons_uki, - &dt_bases_addons_uki, - &dt_sizes_addons_uki, - &dt_filenames_addons_uki, - &n_dts_addons_uki); + &dt_addons_local, + &n_dt_addons_local); if (err != EFI_SUCCESS) log_error_status(err, "Error loading UKI-specific addons, ignoring: %m"); } @@ -945,20 +922,9 @@ static EFI_STATUS run(EFI_HANDLE image) { install_embedded_devicetree(loaded_image, sections, &dt_state); int dtb_measured; - dtb_install_addons(&dt_state, - dt_bases_addons_global, - dt_sizes_addons_global, - dt_filenames_addons_global, - n_dts_addons_global, - &dtb_measured); + install_addon_devicetrees(&dt_state, dt_addons_global, n_dt_addons_global, &dtb_measured); combine_measured_flag(¶meters_measured, dtb_measured); - - dtb_install_addons(&dt_state, - dt_bases_addons_uki, - dt_sizes_addons_uki, - dt_filenames_addons_uki, - n_dts_addons_uki, - &dtb_measured); + install_addon_devicetrees(&dt_state, dt_addons_local, n_dt_addons_local, &dtb_measured); combine_measured_flag(¶meters_measured, dtb_measured); export_pcr_variables(sections_measured, parameters_measured, sysext_measured, confext_measured);