bios-tables-test: handle false-positive smbios signature matches
It has been reported that sometimes the .rodata section of SeaBIOS, containing the constant string against which the SMBIOS signature ends up being compared, also falls within the guest f-segment. In that case, the test obviously fails, unless we continue searching for the *real* SMBIOS entry point. Rather than stopping at the first match for the SMBIOS signature ("_SM_") in the f-segment (0xF0000-0xFFFFF), continue scanning until either a valid entry point table is found, or the f-segment has been exhausted. Reported-by: Bruce Rogers <brogers@suse.com> Signed-off-by: Gabriel Somlo <somlo@cmu.edu> Tested-by: Bruce Rogers <brogers@suse.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
81b2b81062
commit
5efed5a172
@ -599,7 +599,45 @@ static void test_acpi_asl(test_data *data)
|
||||
free_test_data(&exp_data);
|
||||
}
|
||||
|
||||
static void test_smbios_ep_address(test_data *data)
|
||||
static bool smbios_ep_table_ok(test_data *data)
|
||||
{
|
||||
struct smbios_entry_point *ep_table = &data->smbios_ep_table;
|
||||
uint32_t addr = data->smbios_ep_addr;
|
||||
|
||||
ACPI_READ_ARRAY(ep_table->anchor_string, addr);
|
||||
if (memcmp(ep_table->anchor_string, "_SM_", 4)) {
|
||||
return false;
|
||||
}
|
||||
ACPI_READ_FIELD(ep_table->checksum, addr);
|
||||
ACPI_READ_FIELD(ep_table->length, addr);
|
||||
ACPI_READ_FIELD(ep_table->smbios_major_version, addr);
|
||||
ACPI_READ_FIELD(ep_table->smbios_minor_version, addr);
|
||||
ACPI_READ_FIELD(ep_table->max_structure_size, addr);
|
||||
ACPI_READ_FIELD(ep_table->entry_point_revision, addr);
|
||||
ACPI_READ_ARRAY(ep_table->formatted_area, addr);
|
||||
ACPI_READ_ARRAY(ep_table->intermediate_anchor_string, addr);
|
||||
if (memcmp(ep_table->intermediate_anchor_string, "_DMI_", 5)) {
|
||||
return false;
|
||||
}
|
||||
ACPI_READ_FIELD(ep_table->intermediate_checksum, addr);
|
||||
ACPI_READ_FIELD(ep_table->structure_table_length, addr);
|
||||
if (ep_table->structure_table_length == 0) {
|
||||
return false;
|
||||
}
|
||||
ACPI_READ_FIELD(ep_table->structure_table_address, addr);
|
||||
ACPI_READ_FIELD(ep_table->number_of_structures, addr);
|
||||
if (ep_table->number_of_structures == 0) {
|
||||
return false;
|
||||
}
|
||||
ACPI_READ_FIELD(ep_table->smbios_bcd_revision, addr);
|
||||
if (acpi_checksum((uint8_t *)ep_table, sizeof *ep_table) ||
|
||||
acpi_checksum((uint8_t *)ep_table + 0x10, sizeof *ep_table - 0x10)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void test_smbios_entry_point(test_data *data)
|
||||
{
|
||||
uint32_t off;
|
||||
|
||||
@ -613,40 +651,15 @@ static void test_smbios_ep_address(test_data *data)
|
||||
}
|
||||
|
||||
if (!memcmp(sig, "_SM_", sizeof sig)) {
|
||||
break;
|
||||
/* signature match, but is this a valid entry point? */
|
||||
data->smbios_ep_addr = off;
|
||||
if (smbios_ep_table_ok(data)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_cmphex(off, <, 0x100000);
|
||||
data->smbios_ep_addr = off;
|
||||
}
|
||||
|
||||
static void test_smbios_ep_table(test_data *data)
|
||||
{
|
||||
struct smbios_entry_point *ep_table = &data->smbios_ep_table;
|
||||
uint32_t addr = data->smbios_ep_addr;
|
||||
|
||||
ACPI_READ_ARRAY(ep_table->anchor_string, addr);
|
||||
g_assert(!memcmp(ep_table->anchor_string, "_SM_", 4));
|
||||
ACPI_READ_FIELD(ep_table->checksum, addr);
|
||||
ACPI_READ_FIELD(ep_table->length, addr);
|
||||
ACPI_READ_FIELD(ep_table->smbios_major_version, addr);
|
||||
ACPI_READ_FIELD(ep_table->smbios_minor_version, addr);
|
||||
ACPI_READ_FIELD(ep_table->max_structure_size, addr);
|
||||
ACPI_READ_FIELD(ep_table->entry_point_revision, addr);
|
||||
ACPI_READ_ARRAY(ep_table->formatted_area, addr);
|
||||
ACPI_READ_ARRAY(ep_table->intermediate_anchor_string, addr);
|
||||
g_assert(!memcmp(ep_table->intermediate_anchor_string, "_DMI_", 5));
|
||||
ACPI_READ_FIELD(ep_table->intermediate_checksum, addr);
|
||||
ACPI_READ_FIELD(ep_table->structure_table_length, addr);
|
||||
g_assert_cmpuint(ep_table->structure_table_length, >, 0);
|
||||
ACPI_READ_FIELD(ep_table->structure_table_address, addr);
|
||||
ACPI_READ_FIELD(ep_table->number_of_structures, addr);
|
||||
g_assert_cmpuint(ep_table->number_of_structures, >, 0);
|
||||
ACPI_READ_FIELD(ep_table->smbios_bcd_revision, addr);
|
||||
g_assert(!acpi_checksum((uint8_t *)ep_table, sizeof *ep_table));
|
||||
g_assert(!acpi_checksum((uint8_t *)ep_table + 0x10,
|
||||
sizeof *ep_table - 0x10));
|
||||
}
|
||||
|
||||
static inline bool smbios_single_instance(uint8_t type)
|
||||
@ -767,8 +780,7 @@ static void test_acpi_one(const char *params, test_data *data)
|
||||
}
|
||||
}
|
||||
|
||||
test_smbios_ep_address(data);
|
||||
test_smbios_ep_table(data);
|
||||
test_smbios_entry_point(data);
|
||||
test_smbios_structs(data);
|
||||
|
||||
qtest_quit(global_qtest);
|
||||
|
Loading…
Reference in New Issue
Block a user