Skip to content

Commit

Permalink
bios-tables-test: handle false-positive smbios signature matches
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Gabriel Somlo <[email protected]>
Tested-by: Bruce Rogers <[email protected]>
Signed-off-by: Gerd Hoffmann <[email protected]>
  • Loading branch information
Gabriel L. Somlo authored and kraxel committed Jun 10, 2015
1 parent 81b2b81 commit 5efed5a
Showing 1 changed file with 44 additions and 32 deletions.
76 changes: 44 additions & 32 deletions tests/bios-tables-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,35 +599,15 @@ static void test_acpi_asl(test_data *data)
free_test_data(&exp_data);
}

static void test_smbios_ep_address(test_data *data)
{
uint32_t off;

/* find smbios entry point structure */
for (off = 0xf0000; off < 0x100000; off += 0x10) {
uint8_t sig[] = "_SM_";
int i;

for (i = 0; i < sizeof sig - 1; ++i) {
sig[i] = readb(off + i);
}

if (!memcmp(sig, "_SM_", sizeof sig)) {
break;
}
}

g_assert_cmphex(off, <, 0x100000);
data->smbios_ep_addr = off;
}

static void test_smbios_ep_table(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);
g_assert(!memcmp(ep_table->anchor_string, "_SM_", 4));
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);
Expand All @@ -636,17 +616,50 @@ static void test_smbios_ep_table(test_data *data)
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));
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);
g_assert_cmpuint(ep_table->structure_table_length, >, 0);
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);
g_assert_cmpuint(ep_table->number_of_structures, >, 0);
if (ep_table->number_of_structures == 0) {
return false;
}
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));
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;

/* find smbios entry point structure */
for (off = 0xf0000; off < 0x100000; off += 0x10) {
uint8_t sig[] = "_SM_";
int i;

for (i = 0; i < sizeof sig - 1; ++i) {
sig[i] = readb(off + i);
}

if (!memcmp(sig, "_SM_", sizeof sig)) {
/* 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);
}

static inline bool smbios_single_instance(uint8_t type)
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 5efed5a

Please sign in to comment.