ACK: [PATCH 4/6] dmicheck: add test for smbios 3.0.0 entry point

Colin Ian King colin.king at canonical.com
Wed Sep 2 09:20:50 UTC 2015


On 02/09/15 08:36, Ivan Hu wrote:
> Signed-off-by: Ivan Hu <ivan.hu at canonical.com>
> ---
>  src/dmi/dmicheck/dmicheck.c | 157 +++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 154 insertions(+), 3 deletions(-)
> 
> diff --git a/src/dmi/dmicheck/dmicheck.c b/src/dmi/dmicheck/dmicheck.c
> index 02bca98..57a7475 100644
> --- a/src/dmi/dmicheck/dmicheck.c
> +++ b/src/dmi/dmicheck/dmicheck.c
> @@ -85,6 +85,7 @@ typedef struct {
>  } fwts_dmi_used_by_kernel;
>  
>  static bool smbios_found = false;
> +static bool smbios30_found = false;
>  
>  /*
>   *  Table derived by scanning thousands of DMI table dumps from bug reports
> @@ -337,6 +338,23 @@ static void dmi_dump_entry(fwts_framework *fw, fwts_smbios_entry *entry, fwts_sm
>  		fwts_log_info_verbatum(fw, "    BCD Revision 00 indicates compliance with specification stated in Major/Minor Version.");
>  }
>  
> +static void dmi_dump_entry30(fwts_framework *fw, fwts_smbios30_entry *entry)
> +{
> +
> +	fwts_log_info_verbatum(fw, "SMBIOS30 Entry Point Structure:");
> +	fwts_log_info_verbatum(fw, "  Anchor String          : %5.5s", entry->signature);
> +	fwts_log_info_verbatum(fw, "  Checksum               : 0x%2.2" PRIx8, entry->checksum);
> +	fwts_log_info_verbatum(fw, "  Entry Point Length     : 0x%2.2" PRIx8, entry->length);
> +	fwts_log_info_verbatum(fw, "  Major Version          : 0x%2.2" PRIx8, entry->major_version);
> +	fwts_log_info_verbatum(fw, "  Minor Version          : 0x%2.2" PRIx8, entry->minor_version);
> +	fwts_log_info_verbatum(fw, "  Docrev                 : 0x%2.2" PRIx8, entry->docrev);
> +	fwts_log_info_verbatum(fw, "  Entry Point Revision   : 0x%2.2" PRIx8, entry->revision);
> +	fwts_log_info_verbatum(fw, "  Reserved               : 0x%2.2" PRIx8, entry->reserved);
> +	fwts_log_info_verbatum(fw, "  Table maximum size     : 0x%8.8" PRIx32, entry->struct_table_max_size);
> +	fwts_log_info_verbatum(fw, "  Table address          : 0x%16.16" PRIx64, entry->struct_table_address);
> +
> +}
> +
>  static int dmi_sane(fwts_framework *fw, fwts_smbios_entry *entry)
>  {
>  	uint8_t	*table, *ptr;
> @@ -492,6 +510,135 @@ static int smbios_entry_check(fwts_framework *fw)
>  
>  }
>  
> +static int dmi_smbios30_sane(fwts_framework *fw, fwts_smbios30_entry *entry)
> +{
> +	uint8_t	*table, *ptr;
> +	uint8_t struct_length;
> +	uint8_t struct_type = 0;
> +	uint16_t i = 0;
> +	uint32_t table_length = entry->struct_table_max_size;
> +	int ret = FWTS_OK;
> +
> +	ptr = table = fwts_mmap((off_t)entry->struct_table_address,
> +			  (size_t)table_length);
> +	if (table == FWTS_MAP_FAILED) {
> +		fwts_failed(fw, LOG_LEVEL_MEDIUM,
> +			"SMBIOS30TableAddressNotMapped",
> +			"Cannot mmap SMBIOS 3.0 tables from "
> +			"%16.16" PRIx64 "..%16.16" PRIx64 ".",
> +			entry->struct_table_address,
> +			entry->struct_table_address + table_length);
> +			return FWTS_ERROR;
> +	}
> +
> +	while (1)
> +	{
> +		if (ptr > table + table_length) {
> +			fwts_failed(fw, LOG_LEVEL_MEDIUM,
> +				"SMBIOS30TableLengthTooSmall",
> +				"The maximum size indicated by the SMBIOS 3.0 table length is "
> +				"smaller than the dmi data or the DMI end of table not found.");
> +			ret = FWTS_ERROR;
> +			break;
> +		}
> +
> +		struct_type = ptr[0];
> +		struct_length = ptr[1];
> +
> +		if (struct_length < 4) {
> +			fwts_failed(fw, LOG_LEVEL_MEDIUM,
> +				"SMBIOSIllegalTableEntry",
> +				"The size of a DMI entry %" PRIu16 " is illegal, "
> +				"DMI data is either wrong or the SMBIOS Table "
> +				"Pointer is pointing to the wrong memory region.", i);
> +			ret = FWTS_ERROR;
> +			break;
> +		}
> +		ptr += struct_length;
> +
> +		/* Scan for end of DMI entry, must be 2 zero bytes */
> +		while (((ptr - table + 1) < table_length) &&
> +		       ((ptr[0] != 0) || (ptr[1] != 0)))
> +				ptr++;
> +		/* Skip over the two zero bytes */
> +		ptr += 2;
> +
> +		/* We found DMI end of table and inside the maximum length? */
> +		if (struct_type == 127) {
> +			if (ptr <= table + table_length)
> +				break;
> +			else {
> +				fwts_failed(fw, LOG_LEVEL_HIGH,
> +					"SMBIOS30TableLengthTooSmall",
> +					"The end of DMI table marker structure was found "
> +					"but outside the structure table maximum size");
> +				ret = FWTS_ERROR;
> +				break;
> +			}
> +		}
> +	}
> +
> +	(void)fwts_munmap(table, (size_t)entry->struct_table_max_size);
> +
> +	return ret;
> +}
> +
> +static int smbios30_entry_check(fwts_framework *fw)
> +{
> +	void *addr = 0;
> +
> +	fwts_smbios30_entry entry;
> +	uint16_t version;
> +	uint8_t checksum;
> +
> +	if ((addr = fwts_smbios30_find_entry(fw, &entry, &version)) == NULL)
> +		return FWTS_ERROR;
> +
> +	fwts_passed(fw, "Found SMBIOS30 Table Entry Point at %p", addr);
> +	dmi_dump_entry30(fw, &entry);
> +	fwts_log_nl(fw);
> +
> +	checksum = fwts_checksum((uint8_t *)&entry, sizeof(fwts_smbios30_entry));
> +	if (checksum != 0)
> +		fwts_failed(fw, LOG_LEVEL_HIGH,
> +			"SMBIOS30BadChecksum",
> +			"SMBIOS30 Table Entry Point Checksum is 0x%2.2" PRIx8
> +			", should be 0x%2.2" PRIx8,
> +			entry.checksum, (uint8_t)(entry.checksum - checksum));
> +	else
> +		fwts_passed(fw, "SMBIOS30 Table Entry Point Checksum is valid.");
> +
> +	if (entry.length != 0x18) {
> +		fwts_failed(fw, LOG_LEVEL_MEDIUM,
> +			"SMBIOS30BadEntryLength",
> +			"SMBIOS30 Table Entry Point Length is 0x%2.2"  PRIx8
> +			", should be 0x18", entry.length);
> +	} else
> +		fwts_passed(fw, "SMBIOS30 Table Entry Point Length is valid.");
> +
> +	if (entry.reserved)
> +		fwts_failed(fw, LOG_LEVEL_MEDIUM,
> +			"SMBIOSBadReserved",
> +			"SMBIOS30 Table Entry Point Reserved is 0x%2.2" PRIx8
> +			", should be 0", entry.reserved);
> +
> +	if ((entry.revision == 1) && (entry.struct_table_address == 0)) {
> +		fwts_failed(fw, LOG_LEVEL_HIGH,
> +			"SMBIOS30BadTableAddress",
> +			"SMBIOS Table Entry Structure Table Address is NULL and should be defined.");
> +	} else {
> +		/*
> +		 * Now does the SMBIOS 3.0.0 table look sane? If not,
> +		 * the SMBIOS Structure Table could be bad
> +		 */
> +		if (dmi_smbios30_sane(fw, &entry) == FWTS_OK)
> +			fwts_passed(fw, "SMBIOS 3.0 Table Entry Structure Table Address and Length looks valid.");
> +	}
> +
> +	return FWTS_OK;
> +
> +}
> +
>  static int dmicheck_test1(fwts_framework *fw)
>  {
>  
> @@ -499,10 +646,14 @@ static int dmicheck_test1(fwts_framework *fw)
>  		smbios_found = true;
>  	}
>  
> -	if (!smbios_found) {
> +	if (smbios30_entry_check(fw) != FWTS_ERROR) {
> +		smbios30_found = true;
> +	}
> +
> +	if (!smbios_found && !smbios30_found) {
>  		fwts_failed(fw, LOG_LEVEL_HIGH,
>  			"SMBIOSNoEntryPoint",
> -			"Could not find SMBIOS Table Entry Point.");
> +			"Could not find any SMBIOS Table Entry Points.");
>  		return FWTS_ERROR;
>  	}
>  
> @@ -1605,7 +1756,7 @@ static int dmicheck_test2(fwts_framework *fw)
>  }
>  
>  static fwts_framework_minor_test dmicheck_tests[] = {
> -	{ dmicheck_test1, "Find and test SMBIOS Table Entry Point." },
> +	{ dmicheck_test1, "Find and test SMBIOS Table Entry Points." },
>  	{ dmicheck_test2, "Test DMI/SMBIOS tables for errors." },
>  	{ NULL, NULL }
>  };
> 
Acked-by: Colin Ian King <colin.king at canonical.com>



More information about the fwts-devel mailing list