[PATCH] DMI: Fix the way to load SMBIOS 3.x tables via sysfs

songgebird at gmail.com songgebird at gmail.com
Wed Aug 22 11:45:41 UTC 2018


From: Ge Song <ge.song at hxt-semitech.com>

In SMBIOS 3.x specs, the meaning of "Structure table maximum size"
field in SMBIOS Entry Point Structure is "Maximum size of SMBIOS
Structure Table, pointed to by the Structure Table Address, in bytes.
The actual size is guaranteed to be less or equal to the maximum size."

Thus we cannot assume the whole size of SMBIOS segment equals to the
value of entry->struct_table_length.

This fix the DMI test failure in some platforms when the real size of
SMBIOS segment are smaller than the value in "Structure table maximum
size" field

Signed-off-by: Ge Song <ge.song at hxt-semitech.com>
---
 src/dmi/dmicheck/dmicheck.c | 35 +++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/src/dmi/dmicheck/dmicheck.c b/src/dmi/dmicheck/dmicheck.c
index 8497c2ab..3b6ebee5 100644
--- a/src/dmi/dmicheck/dmicheck.c
+++ b/src/dmi/dmicheck/dmicheck.c
@@ -34,6 +34,7 @@
 #include <unistd.h>
 #include <limits.h>
 #include <fcntl.h>
+#include <errno.h>
 
 #define DMI_VERSION			(0x0311)
 #define VERSION_MAJOR(v)		((v) >> 8)
@@ -276,6 +277,38 @@ static int dmi_load_file(const char* filename, void *buf, size_t size)
 	return FWTS_OK;
 }
 
+static int dmi_load_file_variable_size(const char* filename, void *buf, size_t *size)
+{
+	int fd;
+	char *p;
+	ssize_t count;
+	size_t sz, total;
+
+	sz = *size;
+	(void)memset(buf, 0, sz);
+
+	if ((fd = open(filename, O_RDONLY)) < 0)
+		return FWTS_ERROR;
+
+	for (p = buf, total = count = 0; ; p = buf + count) {
+		count = read(fd, p, sz - total);
+		if (count < 0) {
+			if (errno == EAGAIN || errno == EWOULDBLOCK)
+				continue;
+			close(fd);
+			return FWTS_ERROR;
+		}
+		if (count == 0)
+			break;
+
+		total += (size_t)count;
+	}
+
+	(void)close(fd);
+	*size = total;
+	return FWTS_OK;
+}
+
 static void* dmi_table_smbios(fwts_framework *fw, fwts_smbios_entry *entry)
 {
 	off_t addr = (off_t)entry->struct_table_address;
@@ -358,7 +391,7 @@ static void* dmi_table_smbios30(fwts_framework *fw, fwts_smbios30_entry *entry)
 		table = malloc(length);
 		if (!table)
 			return NULL;
-		if (dmi_load_file("/sys/firmware/dmi/tables/DMI", table, length) == FWTS_OK) {
+		if (dmi_load_file_variable_size("/sys/firmware/dmi/tables/DMI", table, &length) == FWTS_OK) {
 			fwts_log_info(fw, "SMBIOS30 table loaded from /sys/firmware/dmi/tables/DMI\n");
 			return table;
 		}
-- 
2.11.0




More information about the fwts-devel mailing list