From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72A95C43219 for ; Thu, 21 Oct 2021 13:00:01 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9402D611CE for ; Thu, 21 Oct 2021 13:00:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 9402D611CE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmx.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 54DA780C72; Thu, 21 Oct 2021 14:59:58 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=gmx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; secure) header.d=gmx.net header.i=@gmx.net header.b="ETDa07fr"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2669283423; Thu, 21 Oct 2021 14:59:56 +0200 (CEST) Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id BA51D80601 for ; Thu, 21 Oct 2021 14:59:49 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xypron.glpk@gmx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1634821187; bh=5pTH8Ro6xwk8Bj3kqTCtTa7l02i8eXBT3T9iKio/QvY=; h=X-UI-Sender-Class:Date:Subject:To:Cc:References:From:In-Reply-To; b=ETDa07frr9Q05NnpQSPEWijJtSbdJAX+HEsi3vPWASFrBHxwWApnuMLFvmxWfda7O MzEoVs8SZr+BAxe2F0Dby59G41HwJ5jwt1oHfRTsK+o9suMPqnFke3CSc2K1dvBaT5 KVEqw3eXBuuumP9n9HZjA/Eh5AuS647b98OF0xIA= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from [192.168.123.55] ([88.152.144.157]) by mail.gmx.net (mrgmx004 [212.227.17.190]) with ESMTPSA (Nemesis) id 1Mnpns-1n2QFF1bbu-00pJq0; Thu, 21 Oct 2021 14:59:47 +0200 Message-ID: Date: Thu, 21 Oct 2021 14:59:46 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.1.2 Subject: Re: [PATCH v3 1/3] efi_loader: add SMBIOS table measurement Content-Language: en-US To: Masahisa Kojima Cc: Ilias Apalodimas , Alexander Graf , Simon Glass , Bin Meng , Christian Gmeiner , U-Boot Mailing List References: <20211001111844.7422-1-masahisa.kojima@linaro.org> <20211001111844.7422-2-masahisa.kojima@linaro.org> <9f72c68b-6d37-f2d1-5f96-036c21157afa@gmx.de> From: Heinrich Schuchardt In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:Bh2eXSLeyg4179hjXu8eEGenyCIu3IZepB7rJOb6Q11jm/mxfPQ g2BhizlEhHxAQoZEEXl2zQUHpP/AsC2U1C6jY2etHgurP0totOG83Tu88wpDj4uxaeZK5CN Ki91yv8RHPNh1W0ZaONL1jIGrbhaRwHvDvv6MjReaEVZuyuC35siV4iRC0Q2PtBJ1Iwm5Ni fMRjhDZFPfkxFL2XCuqnA== X-UI-Out-Filterresults: notjunk:1;V03:K0:ri+MoqxtkyY=:iyKcDeCz3A4K/JExZ1QGb7 QTCpbtB7aP2O0bpWqMxoOPTn5wS8gpS83W2gE63FT66RH8Kq3JLJmsg/BqGrIoduK4/NZc1lM BZSMTF+bttqUxuHQR5Oz3N5gAFvkmsKgJSXADYKwRLTvrzolEyRaq/sp4JeZjqnrH4AAyXrAk IcY32H0QQYr7YCw+OROtmsI3gCvPZMzBHLv1NeBPA1n74a6/T6kXqLe7RH3NP7/I7C8URRXRx n3dKadU9NnlUCu1IzOfqSHvnlBL7q+Y4jIM/OhDJCsYdsMwybhLDJa5pNMV3EbR/rKotpN7L5 GN7D/sCjqmQHXzF/u6VFd1fLSRmtCCTahvr9KokQfVJLo/gavEphwWRkquY2mfnXU8bHCMkvg Raq/I6wfi0uV0UD1W6cHqLb0jw0ch3TNWZDfrazwBxfgoitMUSHI8HY9aJDvsAObxkcDaUD0x AD4A1ldXqRXiNUmNhjibSmMQQDehUBUweZ7LkpI9/uujVKz2GiEUqUVXDKj3Gv5A9vdGxblF2 rgh4jFhsBu79ng3ucIjg73xSE83+vbM/GV2ReHuKHG0GA88CYqfLJJJqMyDp957HKPE7X6RPH mcJVz4OpfkZiiwUoUJ8wp+oRlLO4VjHgBQssh3A4bmYP422FE51e+R3Wc3SkuyqhRN0LqYkuX 0OQz0K/IqIZtTtKIqgTrIq8XllXxp7kNxqaIX6lFnGO7np4r2411c8iCyNjMwme3lWWaNdObB Rq/fUuhJiyxEOZdaFsYYvS5ad4/eM8UXfwtsUfSnQK+I92vWz9MnQwknW/2HjxfcGOHbM6VpF eAwPW46wYUsKEazDkpkuZshNgaLdvLDeKoOlVCU0x5HcMlCQMD+1OFcTPtoLMwPVnpxtdfkUk gHVSfqdhDe0ljiJwiKXh2xrOkBF2fRqMGnAoPPTjzUBqCiXQYB/oyju+ZtyMmmZadMMCqGn3t r5ccvXl61eqUxRaZ4opPQpaeO1zmEpxgW6trcwTXqGUxXH+yL6/f87ppKlBlm5BgFcV/5zD8Z OhLU8vxI7edofX2PH/ub0OAFCiIgDcbAUfehnodDSMdl6HLBviFcDopoJEcQ1lF8CXXwonReR 9nv+tte4uSai1I= X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean On 10/21/21 14:52, Masahisa Kojima wrote: > On Thu, 21 Oct 2021 at 17:49, Heinrich Schuchardt w= rote: >> >> >> >> On 10/21/21 10:38, Masahisa Kojima wrote: >>> On Thu, 21 Oct 2021 at 09:17, Heinrich Schuchardt = wrote: >>>> >>>> On 10/1/21 1:18 PM, Masahisa Kojima wrote: >>>>> TCG PC Client spec requires to measure the SMBIOS >>>> >>>> I guess you mean the "TCG PC Client Platform Firmware Profile >>>> Specification"? Please, provide the full name in the commit message. >>> >>> Sorry, I will write full spec name. >>> >>>> >>>>> table that contain static configuration information >>>>> (e.g. Platform Manufacturer Enterprise Number assigned by IANA, >>>>> platform model number, Vendor and Device IDs for each SMBIOS table). >>>>> >>>>> The device- and environment-dependent information such as >>>>> serial number is cleared to zero or space character for >>>>> the measurement. >>>> >>>> This contradicts the spec requiring the device IDs (i.e. the serial >>>> number) to be measured. You don't want to get the same measurement wh= en >>>> the device is swapped. >>> >>> In my understanding, the same measurement result is expected >>> among one product. Even if the device is swapped, measurement is the s= ame. >>> If device unique information such as serial number >>> is included in the measurement, attestation process will be very compl= icated. >>> >>>> >>>>> >>>>> Existing smbios_string() function returns pointer to the string >>>>> with const qualifier, but exisintg use case is updating version >>>>> string and const qualifier must be removed. >>>>> This commit removes const qualifier from smbios_string() >>>>> return value and reuses to clear the strings for the measurement. >>>>> >>>>> This commit also fixes the following compiler warning: >>>>> >>>>> lib/smbios-parser.c:59:39: warning: cast to pointer from integer of >>>>> different size [-Wint-to-pointer-cast] >>>>> const struct smbios_header *header =3D (struct smbios_header *)= entry->struct_table_address; >>>>> >>>>> Signed-off-by: Masahisa Kojima >>>>> --- >>>>> >>>>> Changes in v3: >>>>> - TCG spec says EV_SEPARATOR must be the last, >>>>> swap the order of measurement >>>>> >>>>> Changes in v2: >>>>> - use flexible array for table_entry field >>>>> - modify funtion name to find_smbios_table() >>>>> - remove unnecessary const qualifier from smbios_string() >>>>> - create non-const version of next_header() >>>>> >>>>> include/efi_loader.h | 2 + >>>>> include/efi_tcg2.h | 15 ++++ >>>>> include/smbios.h | 17 +++- >>>>> lib/efi_loader/Kconfig | 1 + >>>>> lib/efi_loader/efi_boottime.c | 2 + >>>>> lib/efi_loader/efi_smbios.c | 2 - >>>>> lib/efi_loader/efi_tcg2.c | 84 +++++++++++++++++++ >>>>> lib/smbios-parser.c | 152 ++++++++++++++++++++++++++++= +++--- >>>>> 8 files changed, 261 insertions(+), 14 deletions(-) >>>>> >>>>> diff --git a/include/efi_loader.h b/include/efi_loader.h >>>>> index c440962fe5..13f0c24058 100644 >>>>> --- a/include/efi_loader.h >>>>> +++ b/include/efi_loader.h >>>>> @@ -308,6 +308,8 @@ extern const efi_guid_t efi_guid_capsule_report; >>>>> extern const efi_guid_t efi_guid_firmware_management_protocol; >>>>> /* GUID for the ESRT */ >>>>> extern const efi_guid_t efi_esrt_guid; >>>>> +/* GUID of the SMBIOS table */ >>>>> +extern const efi_guid_t smbios_guid; >>>>> >>>>> extern char __efi_runtime_start[], __efi_runtime_stop[]; >>>>> extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[]; >>>>> diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h >>>>> index 8f02d4fb0b..ca66695b39 100644 >>>>> --- a/include/efi_tcg2.h >>>>> +++ b/include/efi_tcg2.h >>>>> @@ -210,6 +210,21 @@ struct efi_tcg2_uefi_variable_data { >>>>> u8 variable_data[1]; >>>>> }; >>>>> >>>>> +/** >>>>> + * struct tdUEFI_HANDOFF_TABLE_POINTERS2 - event log structure of S= MBOIS tables >>>>> + * @table_description_size: size of table description >>>>> + * @table_description: table description >>>>> + * @number_of_tables: number of uefi configuration t= able >>>>> + * @table_entry: uefi configuration table entry >>>>> + */ >>>>> +#define SMBIOS_HANDOFF_TABLE_DESC "SmbiosTable" >>>>> +struct smbios_handoff_table_pointers2 { >>>>> + u8 table_description_size; >>>>> + u8 table_description[sizeof(SMBIOS_HANDOFF_TABLE_DESC)]; >>>>> + u64 number_of_tables; >>>>> + struct efi_configuration_table table_entry[]; >>>>> +} __packed; >>>>> + >>>>> struct efi_tcg2_protocol { >>>>> efi_status_t (EFIAPI * get_capability)(struct efi_tcg2_proto= col *this, >>>>> struct efi_tcg2_boot_= service_capability *capability); >>>>> diff --git a/include/smbios.h b/include/smbios.h >>>>> index aa6b6f3849..acfcbfe2ca 100644 >>>>> --- a/include/smbios.h >>>>> +++ b/include/smbios.h >>>>> @@ -260,9 +260,9 @@ const struct smbios_header *smbios_header(const = struct smbios_entry *entry, int >>>>> * >>>>> * @header: pointer to struct smbios_header >>>>> * @index: string index >>>>> - * @return: NULL or a valid const char pointer >>>>> + * @return: NULL or a valid char pointer >>>>> */ >>>>> -const char *smbios_string(const struct smbios_header *header, int i= ndex); >>>>> +char *smbios_string(const struct smbios_header *header, int index); >>>> >>>> This looks wrong. Your code is changing the actual SMBIOS table that = we >>>> will pass via an UEFI configuration table. Why would you do this? For >>>> instance the serial number is an information that you actually want t= o >>>> see in the operating system. I think you should first copy the string >>>> and then manipulate the copy if this is necessary for the measurement= . >>> >>> No, I prepare the copied SMBIOS table and update it for the measuremen= t. >> >> Then why do you move from const char * to char *? >> >> You are passing in a const struct smbios_header *header. This implies >> that every part of this structure is const. This is a contract with the >> caller that every part of the table will be treated as const. You shoul= d >> not return anything as not const. > > struct smbios_header only has following members. > > struct __packed smbios_header { > u8 type; > u8 length; > u16 handle; > }; > > SMBIOS table is like following. > > struct smbios_header; > struct type0_specific_info; > "index1 string\0" > "index2 string\0" > "\0\0" > struct smbios_header; > struct type1_specific_info; > "index1 string\0" > ... > > + char *smbios_string(const struct smbios_header *header, int index) > > smbios_string() function will not update input smbios_header, and return > the char pointer to the string specified by "index" argument, to > update the string > by caller. > So I think there is no problem. I would prefer if you leave the signature as is. If header points to a copy that your code has created, you can cast the return value to (char *). That way the function does what is expected and the deviation will be restricted to your specific usage. Best regards Heinrich > > Best Regards, > Masahisa Kojima > > > Thanks, > Masahisa Kojima > >> >> Best regards >> >> Heinrich >> >>> >>> tcg2_measure_smbios(): >>> + smbios_copy =3D (struct smbios_header >>> *)((uintptr_t)&event->table_entry[0].table); >>> + memcpy(&event->table_entry[0].table, >>> + (void *)((uintptr_t)entry->struct_table_address), >>> + entry->struct_table_length); >>> + >>> + smbios_prepare_measurement(entry, smbios_copy); >>> >>> I have tested that linux can show the original SMBIOS table >>> by "dmidocode" command. >>> >>> Thanks, >>> Masahisa Kojima >>> >>>> >>>> Best regards >>>> >>>> Heinrich >>>> >>>>> >>>>> /** >>>>> * smbios_update_version() - Update the version string >>>>> @@ -292,4 +292,17 @@ int smbios_update_version(const char *version); >>>>> */ >>>>> int smbios_update_version_full(void *smbios_tab, const char *ver= sion); >>>>> >>>>> +/** >>>>> + * smbios_prepare_measurement() - Update smbios table for the measu= rement >>>>> + * >>>>> + * TCG specification requires to measure static configuration infor= mation. >>>>> + * This function clear the device dependent parameters such as >>>>> + * serial number for the measurement. >>>>> + * >>>>> + * @entry: pointer to a struct smbios_entry >>>>> + * @header: pointer to a struct smbios_header >>>>> + */ >>>>> +void smbios_prepare_measurement(const struct smbios_entry *entry, >>>>> + struct smbios_header *header); >>>>> + >>>>> #endif /* _SMBIOS_H_ */ >>>>> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig >>>>> index f48d9e8b51..e691b1ea96 100644 >>>>> --- a/lib/efi_loader/Kconfig >>>>> +++ b/lib/efi_loader/Kconfig >>>>> @@ -320,6 +320,7 @@ config EFI_TCG2_PROTOCOL >>>>> select SHA384 >>>>> select SHA512 >>>>> select HASH >>>>> + select SMBIOS_PARSER >>>>> help >>>>> Provide a EFI_TCG2_PROTOCOL implementation using the TPM h= ardware >>>>> of the platform. >>>>> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boot= time.c >>>>> index f0283b539e..701e2212c8 100644 >>>>> --- a/lib/efi_loader/efi_boottime.c >>>>> +++ b/lib/efi_loader/efi_boottime.c >>>>> @@ -86,6 +86,8 @@ const efi_guid_t efi_guid_event_group_reset_system= =3D >>>>> /* GUIDs of the Load File and Load File2 protocols */ >>>>> const efi_guid_t efi_guid_load_file_protocol =3D EFI_LOAD_FILE_P= ROTOCOL_GUID; >>>>> const efi_guid_t efi_guid_load_file2_protocol =3D EFI_LOAD_FILE2= _PROTOCOL_GUID; >>>>> +/* GUID of the SMBIOS table */ >>>>> +const efi_guid_t smbios_guid =3D SMBIOS_TABLE_GUID; >>>>> >>>>> static efi_status_t EFIAPI efi_disconnect_controller( >>>>> efi_handle_t controller_hand= le, >>>>> diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios= .c >>>>> index 2eb4cb1c1a..fc0b23397c 100644 >>>>> --- a/lib/efi_loader/efi_smbios.c >>>>> +++ b/lib/efi_loader/efi_smbios.c >>>>> @@ -13,8 +13,6 @@ >>>>> #include >>>>> #include >>>>> >>>>> -static const efi_guid_t smbios_guid =3D SMBIOS_TABLE_GUID; >>>>> - >>>>> /* >>>>> * Install the SMBIOS table as a configuration table. >>>>> * >>>>> diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c >>>>> index d3b8f93f14..f14d4d6da1 100644 >>>>> --- a/lib/efi_loader/efi_tcg2.c >>>>> +++ b/lib/efi_loader/efi_tcg2.c >>>>> @@ -14,6 +14,7 @@ >>>>> #include >>>>> #include >>>>> #include >>>>> +#include >>>>> #include >>>>> #include >>>>> #include >>>>> @@ -1455,6 +1456,81 @@ error: >>>>> return ret; >>>>> } >>>>> >>>>> +/** >>>>> + * tcg2_measure_smbios() - measure smbios table >>>>> + * >>>>> + * @dev: TPM device >>>>> + * @entry: pointer to the smbios_entry structure >>>>> + * >>>>> + * Return: status code >>>>> + */ >>>>> +static efi_status_t >>>>> +tcg2_measure_smbios(struct udevice *dev, >>>>> + const struct smbios_entry *entry) >>>>> +{ >>>>> + efi_status_t ret; >>>>> + struct smbios_header *smbios_copy; >>>>> + struct smbios_handoff_table_pointers2 *event =3D NULL; >>>>> + u32 event_size; >>>>> + >>>>> + /* >>>>> + * TCG PC Client PFP Spec says >>>>> + * "SMBIOS structures that contain static configuration inform= ation >>>>> + * (e.g. Platform Manufacturer Enterprise Number assigned by I= ANA, >>>>> + * platform model number, Vendor and Device IDs for each SMBIO= S table) >>>>> + * that is relevant to the security of the platform MUST be me= asured". >>>>> + * Device dependent parameters such as serial number are clear= ed to >>>>> + * zero or spaces for the measurement. >>>>> + */ >>>>> + event_size =3D sizeof(struct smbios_handoff_table_pointers2) + >>>>> + FIELD_SIZEOF(struct efi_configuration_table, guid= ) + >>>>> + entry->struct_table_length; >>>>> + event =3D calloc(1, event_size); >>>>> + if (!event) { >>>>> + ret =3D EFI_OUT_OF_RESOURCES; >>>>> + goto out; >>>>> + } >>>>> + >>>>> + event->table_description_size =3D sizeof(SMBIOS_HANDOFF_TABLE_= DESC); >>>>> + memcpy(event->table_description, SMBIOS_HANDOFF_TABLE_DESC, >>>>> + sizeof(SMBIOS_HANDOFF_TABLE_DESC)); >>>>> + put_unaligned_le64(1, &event->number_of_tables); >>>>> + guidcpy(&event->table_entry[0].guid, &smbios_guid); >>>>> + smbios_copy =3D (struct smbios_header *)((uintptr_t)&event->ta= ble_entry[0].table); >>>>> + memcpy(&event->table_entry[0].table, >>>>> + (void *)((uintptr_t)entry->struct_table_address), >>>>> + entry->struct_table_length); >>>>> + >>>>> + smbios_prepare_measurement(entry, smbios_copy); >>>>> + >>>>> + ret =3D tcg2_measure_event(dev, 1, EV_EFI_HANDOFF_TABLES2, eve= nt_size, >>>>> + (u8 *)event); >>>>> + if (ret !=3D EFI_SUCCESS) >>>>> + goto out; >>>>> + >>>>> +out: >>>>> + free(event); >>>>> + >>>>> + return ret; >>>>> +} >>>>> + >>>>> +/** >>>>> + * find_smbios_table() - find smbios table >>>>> + * >>>>> + * Return: pointer to the smbios table >>>>> + */ >>>>> +static void *find_smbios_table(void) >>>>> +{ >>>>> + u32 i; >>>>> + >>>>> + for (i =3D 0; i < systab.nr_tables; i++) { >>>>> + if (!guidcmp(&smbios_guid, &systab.tables[i].guid)) >>>>> + return systab.tables[i].table; >>>>> + } >>>>> + >>>>> + return NULL; >>>>> +} >>>>> + >>>>> /** >>>>> * efi_tcg2_measure_efi_app_invocation() - measure efi app invoc= ation >>>>> * >>>>> @@ -1466,6 +1542,7 @@ efi_status_t efi_tcg2_measure_efi_app_invocati= on(void) >>>>> u32 pcr_index; >>>>> struct udevice *dev; >>>>> u32 event =3D 0; >>>>> + struct smbios_entry *entry; >>>>> >>>>> if (tcg2_efi_app_invoked) >>>>> return EFI_SUCCESS; >>>>> @@ -1484,6 +1561,13 @@ efi_status_t efi_tcg2_measure_efi_app_invocat= ion(void) >>>>> if (ret !=3D EFI_SUCCESS) >>>>> goto out; >>>>> >>>>> + entry =3D (struct smbios_entry *)find_smbios_table(); >>>>> + if (entry) { >>>>> + ret =3D tcg2_measure_smbios(dev, entry); >>>>> + if (ret !=3D EFI_SUCCESS) >>>>> + goto out; >>>>> + } >>>>> + >>>>> for (pcr_index =3D 0; pcr_index <=3D 7; pcr_index++) { >>>>> ret =3D tcg2_measure_event(dev, pcr_index, EV_SEPARA= TOR, >>>>> sizeof(event), (u8 *)&event= ); >>>>> diff --git a/lib/smbios-parser.c b/lib/smbios-parser.c >>>>> index 34203f952c..596a967302 100644 >>>>> --- a/lib/smbios-parser.c >>>>> +++ b/lib/smbios-parser.c >>>>> @@ -39,10 +39,8 @@ const struct smbios_entry *smbios_entry(u64 addre= ss, u32 size) >>>>> return entry; >>>>> } >>>>> >>>>> -static const struct smbios_header *next_header(const struct smbios_= header *curr) >>>>> +static u8 *find_next_header(u8 *pos) >>>>> { >>>>> - u8 *pos =3D ((u8 *)curr) + curr->length; >>>>> - >>>>> /* search for _double_ NULL bytes */ >>>>> while (!((*pos =3D=3D 0) && (*(pos + 1) =3D=3D 0))) >>>>> pos++; >>>>> @@ -50,13 +48,27 @@ static const struct smbios_header *next_header(c= onst struct smbios_header *curr) >>>>> /* step behind the double NULL bytes */ >>>>> pos +=3D 2; >>>>> >>>>> - return (struct smbios_header *)pos; >>>>> + return pos; >>>>> +} >>>>> + >>>>> +static struct smbios_header *get_next_header(struct smbios_header *= curr) >>>>> +{ >>>>> + u8 *pos =3D ((u8 *)curr) + curr->length; >>>>> + >>>>> + return (struct smbios_header *)find_next_header(pos); >>>>> +} >>>>> + >>>>> +static const struct smbios_header *next_header(const struct smbios_= header *curr) >>>>> +{ >>>>> + u8 *pos =3D ((u8 *)curr) + curr->length; >>>>> + >>>>> + return (struct smbios_header *)find_next_header(pos); >>>>> } >>>>> >>>>> const struct smbios_header *smbios_header(const struct smbios_en= try *entry, int type) >>>>> { >>>>> const unsigned int num_header =3D entry->struct_count; >>>>> - const struct smbios_header *header =3D (struct smbios_header *= )entry->struct_table_address; >>>>> + const struct smbios_header *header =3D (struct smbios_header *= )((uintptr_t)entry->struct_table_address); >>>>> >>>>> for (unsigned int i =3D 0; i < num_header; i++) { >>>>> if (header->type =3D=3D type) >>>>> @@ -68,8 +80,8 @@ const struct smbios_header *smbios_header(const st= ruct smbios_entry *entry, int >>>>> return NULL; >>>>> } >>>>> >>>>> -static const char *string_from_smbios_table(const struct smbios_hea= der *header, >>>>> - int idx) >>>>> +static char *string_from_smbios_table(const struct smbios_header *h= eader, >>>>> + int idx) >>>>> { >>>>> unsigned int i =3D 1; >>>>> u8 *pos; >>>>> @@ -86,10 +98,10 @@ static const char *string_from_smbios_table(cons= t struct smbios_header *header, >>>>> pos++; >>>>> } >>>>> >>>>> - return (const char *)pos; >>>>> + return (char *)pos; >>>>> } >>>>> >>>>> -const char *smbios_string(const struct smbios_header *header, int i= ndex) >>>>> +char *smbios_string(const struct smbios_header *header, int index) >>>>> { >>>>> if (!header) >>>>> return NULL; >>>>> @@ -109,7 +121,7 @@ int smbios_update_version_full(void *smbios_tab,= const char *version) >>>>> if (!hdr) >>>>> return log_msg_ret("tab", -ENOENT); >>>>> bios =3D (struct smbios_type0 *)hdr; >>>>> - ptr =3D (char *)smbios_string(hdr, bios->bios_ver); >>>>> + ptr =3D smbios_string(hdr, bios->bios_ver); >>>>> if (!ptr) >>>>> return log_msg_ret("str", -ENOMEDIUM); >>>>> >>>>> @@ -132,3 +144,123 @@ int smbios_update_version_full(void *smbios_ta= b, const char *version) >>>>> >>>>> return 0; >>>>> } >>>>> + >>>>> +struct smbios_filter_param { >>>>> + u32 offset; >>>>> + u32 size; >>>>> + bool is_string; >>>>> +}; >>>>> + >>>>> +struct smbios_filter_table { >>>>> + int type; >>>>> + struct smbios_filter_param *params; >>>>> + u32 count; >>>>> +}; >>>>> + >>>>> +struct smbios_filter_param smbios_type1_filter_params[] =3D { >>>>> + {offsetof(struct smbios_type1, serial_number), >>>>> + FIELD_SIZEOF(struct smbios_type1, serial_number), true}, >>>>> + {offsetof(struct smbios_type1, uuid), >>>>> + FIELD_SIZEOF(struct smbios_type1, uuid), false}, >>>>> + {offsetof(struct smbios_type1, wakeup_type), >>>>> + FIELD_SIZEOF(struct smbios_type1, wakeup_type), false}, >>>>> +}; >>>>> + >>>>> +struct smbios_filter_param smbios_type2_filter_params[] =3D { >>>>> + {offsetof(struct smbios_type2, serial_number), >>>>> + FIELD_SIZEOF(struct smbios_type2, serial_number), true}, >>>>> + {offsetof(struct smbios_type2, chassis_location), >>>>> + FIELD_SIZEOF(struct smbios_type2, chassis_location), false}, >>>>> +}; >>>>> + >>>>> +struct smbios_filter_param smbios_type3_filter_params[] =3D { >>>>> + {offsetof(struct smbios_type3, serial_number), >>>>> + FIELD_SIZEOF(struct smbios_type3, serial_number), true}, >>>>> + {offsetof(struct smbios_type3, asset_tag_number), >>>>> + FIELD_SIZEOF(struct smbios_type3, asset_tag_number), true}, >>>>> +}; >>>>> + >>>>> +struct smbios_filter_param smbios_type4_filter_params[] =3D { >>>>> + {offsetof(struct smbios_type4, serial_number), >>>>> + FIELD_SIZEOF(struct smbios_type4, serial_number), true}, >>>>> + {offsetof(struct smbios_type4, asset_tag), >>>>> + FIELD_SIZEOF(struct smbios_type4, asset_tag), true}, >>>>> + {offsetof(struct smbios_type4, part_number), >>>>> + FIELD_SIZEOF(struct smbios_type4, part_number), true}, >>>>> + {offsetof(struct smbios_type4, core_count), >>>>> + FIELD_SIZEOF(struct smbios_type4, core_count), false}, >>>>> + {offsetof(struct smbios_type4, core_enabled), >>>>> + FIELD_SIZEOF(struct smbios_type4, core_enabled), false}, >>>>> + {offsetof(struct smbios_type4, thread_count), >>>>> + FIELD_SIZEOF(struct smbios_type4, thread_count), false}, >>>>> + {offsetof(struct smbios_type4, core_count2), >>>>> + FIELD_SIZEOF(struct smbios_type4, core_count2), false}, >>>>> + {offsetof(struct smbios_type4, core_enabled2), >>>>> + FIELD_SIZEOF(struct smbios_type4, core_enabled2), false}, >>>>> + {offsetof(struct smbios_type4, thread_count), >>>>> + FIELD_SIZEOF(struct smbios_type4, thread_count2), false}, >>>>> + {offsetof(struct smbios_type4, voltage), >>>>> + FIELD_SIZEOF(struct smbios_type4, voltage), false}, >>>>> +}; >>>>> + >>>>> +struct smbios_filter_table smbios_filter_tables[] =3D { >>>>> + {SMBIOS_SYSTEM_INFORMATION, smbios_type1_filter_params, >>>>> + ARRAY_SIZE(smbios_type1_filter_params)}, >>>>> + {SMBIOS_BOARD_INFORMATION, smbios_type2_filter_params, >>>>> + ARRAY_SIZE(smbios_type2_filter_params)}, >>>>> + {SMBIOS_SYSTEM_ENCLOSURE, smbios_type3_filter_params, >>>>> + ARRAY_SIZE(smbios_type3_filter_params)}, >>>>> + {SMBIOS_PROCESSOR_INFORMATION, smbios_type4_filter_params, >>>>> + ARRAY_SIZE(smbios_type4_filter_params)}, >>>>> +}; >>>>> + >>>>> +static void clear_smbios_table(struct smbios_header *header, >>>>> + struct smbios_filter_param *filter, >>>>> + u32 count) >>>>> +{ >>>>> + u32 i; >>>>> + char *str; >>>>> + u8 string_id; >>>>> + >>>>> + for (i =3D 0; i < count; i++) { >>>>> + if (filter[i].is_string) { >>>>> + string_id =3D *((u8 *)header + filter[i].offse= t); >>>>> + if (string_id =3D=3D 0) /* string is empty */ >>>>> + continue; >>>>> + >>>>> + str =3D smbios_string(header, string_id); >>>>> + if (!str) >>>>> + continue; >>>>> + >>>>> + /* string is cleared to space, keep '\0' termi= nator */ >>>>> + memset(str, ' ', strlen(str)); >>>>> + >>>>> + } else { >>>>> + memset((void *)((u8 *)header + filter[i].offse= t), >>>>> + 0, filter[i].size); >>>>> + } >>>>> + } >>>>> +} >>>>> + >>>>> +void smbios_prepare_measurement(const struct smbios_entry *entry, >>>>> + struct smbios_header *smbios_copy) >>>>> +{ >>>>> + u32 i, j; >>>>> + struct smbios_header *header; >>>>> + >>>>> + for (i =3D 0; i < ARRAY_SIZE(smbios_filter_tables); i++) { >>>>> + header =3D smbios_copy; >>>>> + for (j =3D 0; j < entry->struct_count; j++) { >>>>> + if (header->type =3D=3D smbios_filter_tables[i= ].type) >>>>> + break; >>>>> + >>>>> + header =3D get_next_header(header); >>>>> + } >>>>> + if (j >=3D entry->struct_count) >>>>> + continue; >>>>> + >>>>> + clear_smbios_table(header, >>>>> + smbios_filter_tables[i].params, >>>>> + smbios_filter_tables[i].count); >>>>> + } >>>>> +} >>>>> >>>>