From patchwork Thu Apr 11 17:51:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruce Rogers X-Patchwork-Id: 10896547 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1A339139A for ; Thu, 11 Apr 2019 17:52:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 08D5828D3E for ; Thu, 11 Apr 2019 17:52:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F14F228D64; Thu, 11 Apr 2019 17:52:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F21F028D3E for ; Thu, 11 Apr 2019 17:52:39 +0000 (UTC) Received: from localhost ([127.0.0.1]:52890 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hEdsM-0001jX-Re for patchwork-qemu-devel@patchwork.kernel.org; Thu, 11 Apr 2019 13:52:38 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58668) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hEdrh-0001QQ-VS for qemu-devel@nongnu.org; Thu, 11 Apr 2019 13:51:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hEdrg-0005ke-1U for qemu-devel@nongnu.org; Thu, 11 Apr 2019 13:51:57 -0400 Received: from inet-orm.provo.novell.com ([137.65.248.124]:48681 helo=mail.novell.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hEdre-0005ZR-6X for qemu-devel@nongnu.org; Thu, 11 Apr 2019 13:51:54 -0400 Received: from brogers1.provo.novell.com (brogers1.dnsdhcp.provo.novell.com [137.65.133.7]) by mail.novell.com with ESMTP (NOT encrypted); Thu, 11 Apr 2019 11:51:43 -0600 From: Bruce Rogers To: qemu-devel@nongnu.org Date: Thu, 11 Apr 2019 11:51:38 -0600 Message-Id: <20190411175138.12838-1-brogers@suse.com> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 137.65.248.124 Subject: [Qemu-devel] [PATCH] hw/smbios: handle both file formats regardless of machine type X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Bruce Rogers , mst@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP It's easy enough to handle either per-spec or legacy smbios structures in the smbios file input without regard to the machine type used, by simply applying the basic smbios formatting rules. then depending on what is detected. terminal numm bytes are added or removed for machine type specific processing. Signed-off-by: Bruce Rogers --- hw/smbios/smbios.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c index 47be9071fa..d4b95ebc84 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -960,6 +960,7 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) struct smbios_structure_header *header; int size; struct smbios_table *table; /* legacy mode only */ + uint8_t *dbl_nulls, *orig_end; qemu_opts_validate(opts, qemu_smbios_file_opts, &err); if (err) { @@ -974,11 +975,21 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) } /* - * NOTE: standard double '\0' terminator expected, per smbios spec. - * (except in legacy mode, where the second '\0' is implicit and - * will be inserted by the BIOS). + * NOTE: standard double '\0' terminator expected, per smbios spec, + * unless the data is formatted for legacy mode, which is used by + * pc-i440fx-2.0 and earlier machine types. Legacy mode structures + * without strings have no '\0' terminators, and those with strings + * also don't have an additional '\0' terminator at the end of the + * final string '\0' terminator. The BIOS will add the '\0' terminators + * to comply with the smbios spec. + * For greater compatibility, regardless of the machine type used, + * either format is accepted. */ - smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size); + smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size + 2); + orig_end = smbios_tables + smbios_tables_len + size; + /* add extra null bytes to end in case of legacy file data */ + *orig_end = '\0'; + *(orig_end + 1) = '\0'; header = (struct smbios_structure_header *)(smbios_tables + smbios_tables_len); @@ -993,6 +1004,19 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) header->type); return; } + for (dbl_nulls = smbios_tables + smbios_tables_len + header->length; + dbl_nulls + 2 <= orig_end; dbl_nulls++) { + if (*dbl_nulls == '\0' && *(dbl_nulls + 1) == '\0') { + break; + } + } + if (dbl_nulls + 2 < orig_end) { + error_setg(errp, "SMBIOS file data malformed"); + return; + } + /* increase size by how many extra nulls were actually needed */ + size += dbl_nulls + 2 - orig_end; + smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size); set_bit(header->type, have_binfile_bitmap); if (header->type == 4) { @@ -1013,6 +1037,17 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) * delete the one we don't need from smbios_set_defaults(), * once we know which machine version has been requested. */ + if (dbl_nulls + 2 == orig_end) { + /* chop off nulls to get legacy format */ + if (header->length + 2 == size) { + size -= 2; + } else { + size -= 1; + } + } else { + /* undo conversion from legacy format to per-spec format */ + size -= dbl_nulls + 2 - orig_end; + } if (!smbios_entries) { smbios_entries_len = sizeof(uint16_t); smbios_entries = g_malloc0(smbios_entries_len);