From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43777) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z0sOE-0003wL-NQ for qemu-devel@nongnu.org; Fri, 05 Jun 2015 10:14:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z0sOC-0006jW-Gb for qemu-devel@nongnu.org; Fri, 05 Jun 2015 10:14:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53384) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z0sOC-0006jB-8b for qemu-devel@nongnu.org; Fri, 05 Jun 2015 10:14:28 -0400 From: Gerd Hoffmann Date: Fri, 5 Jun 2015 16:14:21 +0200 Message-Id: <1433513661-7267-7-git-send-email-kraxel@redhat.com> In-Reply-To: <1433513661-7267-1-git-send-email-kraxel@redhat.com> References: <1433513661-7267-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PULL 6/6] bios-tables-test: handle false-positive smbios signature matches List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: "Gabriel L. Somlo" , Gerd Hoffmann From: "Gabriel L. Somlo" 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 Signed-off-by: Gabriel Somlo Tested-by: Bruce Rogers Signed-off-by: Gerd Hoffmann --- tests/bios-tables-test.c | 76 ++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index 7e85dc4..0de1742 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -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); @@ -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) @@ -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); -- 1.8.3.1