Blob Blame History Raw
From 12fbde92a26da61eda9f2ff0ba3c316779163f10 Mon Sep 17 00:00:00 2001
From: Jean Delvare <jdelvare@suse.de>
Date: Fri, 20 Jan 2017 10:57:12 +0100
Subject: [PATCH 18/19] Only decode one DMI table

Since version 3.0.0 of the SMBIOS specification, there can be
multiple entry points in memory, pointing to one or two DMI tables.
If both a 32-bit ("_SM_") entry point and a 64-bit ("_SM3_") entry
point are present, the specification requires that the latter points
to a table which is a super-set of the table pointed to by the
former. Therefore it makes no sense to decode both.

Per specification, look for a 64-bit ("_SM3_") entry point first, and
if we can't find any, look for a 32-bit ("_SM_" or "_DMI_") entry
point.

This fixes bug #50022:
https://savannah.nongnu.org/bugs/?50022
---
 CHANGELOG   |  6 ++++++
 dmidecode.c | 19 ++++++++++++++-----
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index ac748b0..67aef99 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,9 @@
+2017-01-20  Jean Delvare  <jdelvare@suse.de>
+
+	* dmidecode.c: Only decode one DMI table.
+	  This fixes Savannah bug #50022:
+	  https://savannah.nongnu.org/bugs/?50022
+
 2016-09-22  Jean Delvare  <jdelvare@suse.de>
 
 	* README: Explain that we can no longer support Cygwin.
diff --git a/dmidecode.c b/dmidecode.c
index 3993592..4b46a13 100644
--- a/dmidecode.c
+++ b/dmidecode.c
@@ -4925,28 +4925,37 @@ memory_scan:
 		goto exit_free;
 	}
 
-	for (fp = 0; fp <= 0xFFF0; fp += 16)
+	/* Look for a 64-bit entry point first */
+	for (fp = 0; fp <= 0xFFE0; fp += 16)
 	{
-		if (memcmp(buf + fp, "_SM3_", 5) == 0 && fp <= 0xFFE0)
+		if (memcmp(buf + fp, "_SM3_", 5) == 0)
 		{
 			if (smbios3_decode(buf + fp, opt.devmem, 0))
 			{
 				found++;
-				fp += 16;
+				goto done;
 			}
 		}
-		else if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
+	}
+
+	/* If none found, look for a 32-bit entry point */
+	for (fp = 0; fp <= 0xFFF0; fp += 16)
+	{
+		if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0)
 		{
 			if (smbios_decode(buf + fp, opt.devmem, 0))
 			{
 				found++;
-				fp += 16;
+				goto done;
 			}
 		}
 		else if (memcmp(buf + fp, "_DMI_", 5) == 0)
 		{
 			if (legacy_decode(buf + fp, opt.devmem, 0))
+			{
 				found++;
+				goto done;
+			}
 		}
 	}
 
-- 
2.9.3