chid_match: match UEFI firmware hwid entry with the current smbios data
UEFI firmware type hwids must be matched against the current hardware first. This change implements that. Additionally, some extra validations on the hwids entries have also been added.
This commit is contained in:
committed by
Lennart Poettering
parent
19bd80e29a
commit
1f4f348c8e
+26
-3
@@ -121,12 +121,35 @@ EFI_STATUS chid_match(const void *hwid_buffer, size_t hwid_length, uint32_t matc
|
||||
|
||||
/* Count devices and check validity */
|
||||
for (; (n_devices + 1) * sizeof(*devices) < hwid_length;) {
|
||||
const Device *device = &devices[n_devices];
|
||||
|
||||
if (devices[n_devices].descriptor == DEVICE_DESCRIPTOR_EOL)
|
||||
if (device->descriptor == DEVICE_DESCRIPTOR_EOL)
|
||||
break;
|
||||
if (!IN_SET(DEVICE_TYPE_FROM_DESCRIPTOR(devices[n_devices].descriptor),
|
||||
DEVICE_TYPE_UEFI_FW, DEVICE_TYPE_DEVICETREE))
|
||||
|
||||
uint32_t device_type = DEVICE_TYPE_FROM_DESCRIPTOR(device->descriptor);
|
||||
size_t name_off, off;
|
||||
|
||||
if (!IN_SET(device_type, DEVICE_TYPE_UEFI_FW, DEVICE_TYPE_DEVICETREE))
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
if (device_type == DEVICE_TYPE_DEVICETREE) {
|
||||
off = device->devicetree.compatible_offset;
|
||||
name_off = device->devicetree.name_offset;
|
||||
} else if (device_type == DEVICE_TYPE_UEFI_FW) {
|
||||
off = device->uefi_fw.fwid_offset;
|
||||
name_off = device->uefi_fw.name_offset;
|
||||
} else
|
||||
assert_not_reached();
|
||||
|
||||
if (off >= hwid_length || name_off >= hwid_length)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
/* check for NULL termination */
|
||||
if (off && !memchr((const uint8_t *) hwid_buffer + off, 0, hwid_length - off))
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (name_off && !memchr((const uint8_t *) hwid_buffer + name_off, 0, hwid_length - name_off))
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
n_devices++;
|
||||
}
|
||||
|
||||
|
||||
+55
-30
@@ -345,13 +345,14 @@ static void pe_locate_sections_internal(
|
||||
}
|
||||
}
|
||||
|
||||
static bool looking_for_dtbauto(const char *const section_names[]) {
|
||||
static bool looking_for_dtbauto_or_efifw(const char *const section_names[]) {
|
||||
assert(section_names);
|
||||
|
||||
for (size_t i = 0; section_names[i]; i++)
|
||||
if (pe_section_name_equal(section_names[i], ".dtbauto"))
|
||||
if (pe_section_name_equal(section_names[i], ".dtbauto") ||
|
||||
pe_section_name_equal(section_names[i], ".efifw"))
|
||||
return true;
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void pe_locate_sections(
|
||||
@@ -361,7 +362,7 @@ static void pe_locate_sections(
|
||||
size_t validate_base,
|
||||
PeSectionVector sections[]) {
|
||||
|
||||
if (!looking_for_dtbauto(section_names))
|
||||
if (!looking_for_dtbauto_or_efifw(section_names))
|
||||
return pe_locate_sections_internal(
|
||||
section_table,
|
||||
n_section_table,
|
||||
@@ -377,40 +378,64 @@ static void pe_locate_sections(
|
||||
const void *hwids = NULL;
|
||||
const Device *device = NULL;
|
||||
|
||||
if (!firmware_devicetree_exists()) {
|
||||
/* Find HWIDs table and search for the current device */
|
||||
static const char *const hwid_section_names[] = { ".hwids", NULL };
|
||||
PeSectionVector hwids_section[1] = {};
|
||||
/* Find HWIDs table and search for the current device */
|
||||
static const char *const hwid_section_names[] = { ".hwids", NULL };
|
||||
PeSectionVector hwids_section[1] = {};
|
||||
|
||||
pe_locate_sections_internal(
|
||||
section_table,
|
||||
n_section_table,
|
||||
hwid_section_names,
|
||||
validate_base,
|
||||
/* device_table= */ NULL,
|
||||
/* device= */ NULL,
|
||||
hwids_section);
|
||||
pe_locate_sections_internal(
|
||||
section_table,
|
||||
n_section_table,
|
||||
hwid_section_names,
|
||||
validate_base,
|
||||
/* device_table= */ NULL,
|
||||
/* device= */ NULL,
|
||||
hwids_section);
|
||||
|
||||
if (PE_SECTION_VECTOR_IS_SET(hwids_section)) {
|
||||
hwids = (const uint8_t *) SIZE_TO_PTR(validate_base) + hwids_section[0].memory_offset;
|
||||
if (PE_SECTION_VECTOR_IS_SET(hwids_section)) {
|
||||
hwids = (const uint8_t *) SIZE_TO_PTR(validate_base) + hwids_section[0].memory_offset;
|
||||
EFI_STATUS err;
|
||||
|
||||
EFI_STATUS err = chid_match(hwids, hwids_section[0].memory_size, DEVICE_TYPE_DEVICETREE, &device);
|
||||
if (err != EFI_SUCCESS) {
|
||||
if (!firmware_devicetree_exists()) {
|
||||
err = chid_match(hwids, hwids_section[0].memory_size, DEVICE_TYPE_DEVICETREE, &device);
|
||||
if (err == EFI_SUCCESS)
|
||||
pe_locate_sections_internal(
|
||||
section_table,
|
||||
n_section_table,
|
||||
section_names,
|
||||
validate_base,
|
||||
hwids,
|
||||
device,
|
||||
sections);
|
||||
else
|
||||
log_full(err, err == EFI_NOT_FOUND ? LOG_DEBUG : LOG_ERR,
|
||||
"HWID matching failed, no DT blob will be selected: %m");
|
||||
hwids = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
err = chid_match(hwids, hwids_section[0].memory_size, DEVICE_TYPE_UEFI_FW, &device);
|
||||
if (err == EFI_SUCCESS)
|
||||
pe_locate_sections_internal(
|
||||
section_table,
|
||||
n_section_table,
|
||||
section_names,
|
||||
validate_base,
|
||||
hwids,
|
||||
device,
|
||||
sections);
|
||||
else {
|
||||
log_full(err, err == EFI_NOT_FOUND ? LOG_DEBUG : LOG_ERR,
|
||||
"No UEFI FW will be selected: %m");
|
||||
hwids = NULL;
|
||||
device = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pe_locate_sections_internal(
|
||||
section_table,
|
||||
n_section_table,
|
||||
section_names,
|
||||
validate_base,
|
||||
hwids,
|
||||
device,
|
||||
sections);
|
||||
section_table,
|
||||
n_section_table,
|
||||
section_names,
|
||||
validate_base,
|
||||
hwids,
|
||||
device,
|
||||
sections);
|
||||
}
|
||||
|
||||
static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const PeFileHeader *pe) {
|
||||
|
||||
+1
-1
@@ -599,7 +599,7 @@ static EFI_STATUS load_addons(
|
||||
err = pe_memory_locate_sections(loaded_addon->ImageBase, unified_sections, sections);
|
||||
if (err != EFI_SUCCESS) {
|
||||
log_error_status(err,
|
||||
"Unable to locate embedded .cmdline/.dtb/.dtbauto/.initrd/.ucode sections in %ls, ignoring: %m",
|
||||
"Unable to locate embedded .cmdline/.dtb/.dtbauto/.efifw/.initrd/.ucode sections in %ls, ignoring: %m",
|
||||
items[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user