mirror of
https://github.com/systemd/systemd.git
synced 2026-08-04 15:10:33 +00:00
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.
This commit is contained in:
@@ -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;
|
||||
|
||||
err = tpm_log_tagged_event(
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
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,
|
||||
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;
|
||||
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_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;
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user