diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 9a1a93fade15f5ba1de84b26af6e22321121f872..17c531a480e145dcc31acccbb5eec78990b067cc 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -630,6 +630,17 @@ static efi_status_t EFIAPI efi_locate_device_path(efi_guid_t *protocol, return EFI_EXIT(EFI_NOT_FOUND); } +/* Collapses configuration table entries, removing index i */ +static void efi_remove_configuration_table(int i) +{ + struct efi_configuration_table *this = &efi_conf_table[i]; + struct efi_configuration_table *next = &efi_conf_table[i+1]; + struct efi_configuration_table *end = &efi_conf_table[systab.nr_tables]; + + memmove(this, next, (ulong)end - (ulong)next); + systab.nr_tables--; +} + efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table) { int i; @@ -637,11 +648,17 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table /* Check for guid override */ for (i = 0; i < systab.nr_tables; i++) { if (!guidcmp(guid, &efi_conf_table[i].guid)) { - efi_conf_table[i].table = table; + if (table) + efi_conf_table[i].table = table; + else + efi_remove_configuration_table(i); return EFI_SUCCESS; } } + if (!table) + return EFI_NOT_FOUND; + /* No override, check for overflow */ if (i >= ARRAY_SIZE(efi_conf_table)) return EFI_OUT_OF_RESOURCES;