summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkhali <khali>2015-05-21 19:04:58 +0000
committerkhali <khali>2015-05-21 19:04:58 +0000
commitb76e823c0123f5b8335b01d911973b375e386ed4 (patch)
treeba60c29091cf0d4503527bc3689a8c2e9a7cf612
parente12c754bd8efe3c6e4297b9f5dc7df26e5f8ac80 (diff)
downloaddmidecode-b76e823c0123f5b8335b01d911973b375e386ed4.tar.gz
dmidecode: Fix up invalid DMI type 34 structure length
Several boards have a bug where some type 34 structures have their length incorrectly set to 0x10 instead of 0x0B. This causes the first 5 characters of the device name to be trimmed. It's easy to check and fix, so do it, but warn.
-rw-r--r--CHANGELOG4
-rw-r--r--dmidecode.c27
2 files changed, 31 insertions, 0 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 6af286f..28ebb13 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+2015-05-21 Jean Delvare <jdelvare@suse.de>
+
+ * dmidecode.c: Fix up invalid DMI type 34 structure length.
+
2015-05-13 Jean Delvare <jdelvare@suse.de>
* dmidecode.c: Add support for SMBIOS3 EFI table.
diff --git a/dmidecode.c b/dmidecode.c
index b96bf5c..621f882 100644
--- a/dmidecode.c
+++ b/dmidecode.c
@@ -2928,6 +2928,29 @@ static void dmi_64bit_memory_error_address(u64 code)
* 7.35 Management Device (Type 34)
*/
+/*
+ * Several boards have a bug where some type 34 structures have their
+ * length incorrectly set to 0x10 instead of 0x0B. This causes the
+ * first 5 characters of the device name to be trimmed. It's easy to
+ * check and fix, so do it, but warn.
+ */
+static void dmi_fixup_type_34(struct dmi_header *h)
+{
+ u8 *p = h->data;
+ int i;
+
+ if (h->length != 0x10)
+ return;
+
+ /* Make sure the hidden data is ASCII only */
+ for (i = 0x0B; i < 0x10; i++)
+ if (p[i] < 32 || p[i] >= 127)
+ return;
+
+ printf("Invalid entry length (%u). Fixed up to %u.\n", 0x10, 0x0B);
+ h->length = 0x0B;
+}
+
static const char *dmi_management_device_type(u8 code)
{
/* 7.35.1 */
@@ -4410,6 +4433,10 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
if (h.type == 1 && h.length >= 5)
dmi_set_vendor(dmi_string(&h, data[0x04]));
+ /* Fixup a common mistake */
+ if (h.type == 34)
+ dmi_fixup_type_34(&h);
+
/* look for the next handle */
next = data + h.length;
while ((unsigned long)(next - buf + 1) < len