Blame SOURCES/0008-dmidecode-Use-read_file-to-read-the-DMI-table-from-s.patch

fd304b
From 364055211b1956539c6a6268e111e244e1292c8c Mon Sep 17 00:00:00 2001
fd304b
From: Jean Delvare <jdelvare@suse.de>
fd304b
Date: Mon, 2 Nov 2015 09:45:31 +0100
fd304b
Subject: [PATCH 8/9] dmidecode: Use read_file() to read the DMI table from
fd304b
 sysfs
fd304b
fd304b
We shouldn't use mem_chunk() to read the DMI table from sysfs. This
fd304b
will fail for SMBIOS v3 implementations which specify a maximum length
fd304b
for the table rather than its exact length. The kernel will trim the
fd304b
table to the actual length, so the DMI file will be shorter than the
fd304b
length announced in entry point.
fd304b
fd304b
read_file() fits the bill in this case, as it deals with end of file
fd304b
nicely.
fd304b
fd304b
This also helps with corrupted DMI tables, as the kernel will not
fd304b
export the part of the table that it wasn't able to parse, effectively
fd304b
trimming it.
fd304b
fd304b
This fixes bug #46176:
fd304b
https://savannah.nongnu.org/bugs/?46176
fd304b
Unexpected end of file error
fd304b
---
fd304b
 CHANGELOG   |  3 +++
fd304b
 dmidecode.c | 29 +++++++++++++++++++++--------
fd304b
 2 files changed, 24 insertions(+), 8 deletions(-)
fd304b
fd304b
diff --git a/CHANGELOG b/CHANGELOG
fd304b
index 1e5437a..fcfc244 100644
fd304b
--- a/CHANGELOG
fd304b
+++ b/CHANGELOG
fd304b
@@ -2,6 +2,9 @@
fd304b
 
fd304b
 	* dmidecode.c, util.c, util.h: Let read_file return the actual data
fd304b
 	  size.
fd304b
+	* dmidecode.c: Use read_file to read the DMI table from sysfs.
fd304b
+	  This fixes Savannah bug #46176:
fd304b
+	  https://savannah.nongnu.org/bugs/?46176
fd304b
 
fd304b
 2015-10-21  Xie XiuQi  <xiexiuqi@huawei.com>
fd304b
 
fd304b
diff --git a/dmidecode.c b/dmidecode.c
fd304b
index a43cfd1..16d1823 100644
fd304b
--- a/dmidecode.c
fd304b
+++ b/dmidecode.c
fd304b
@@ -4524,16 +4524,29 @@ static void dmi_table(off_t base, u32 len, u16 num, u16 ver, const char *devmem,
fd304b
 		printf("\n");
fd304b
 	}
fd304b
 
fd304b
-	/*
fd304b
-	 * When we are reading the DMI table from sysfs, we want to print
fd304b
-	 * the address of the table (done above), but the offset of the
fd304b
-	 * data in the file is 0.  When reading from /dev/mem, the offset
fd304b
-	 * in the file is the address.
fd304b
-	 */
fd304b
 	if (flags & FLAG_NO_FILE_OFFSET)
fd304b
-		base = 0;
fd304b
+	{
fd304b
+		/*
fd304b
+		 * When reading from sysfs, the file may be shorter than
fd304b
+		 * announced. For SMBIOS v3 this is expcted, as we only know
fd304b
+		 * the maximum table size, not the actual table size. For older
fd304b
+		 * implementations (and for SMBIOS v3 too), this would be the
fd304b
+		 * result of the kernel truncating the table on parse error.
fd304b
+		 */
fd304b
+		size_t size = len;
fd304b
+		buf = read_file(&size, devmem);
fd304b
+		if (!(opt.flags & FLAG_QUIET) && num && size != (size_t)len)
fd304b
+		{
fd304b
+			printf("Wrong DMI structures length: %u bytes "
fd304b
+				"announced, only %lu bytes available.\n",
fd304b
+				len, (unsigned long)size);
fd304b
+		}
fd304b
+		len = size;
fd304b
+	}
fd304b
+	else
fd304b
+		buf = mem_chunk(base, len, devmem);
fd304b
 
fd304b
-	if ((buf = mem_chunk(base, len, devmem)) == NULL)
fd304b
+	if (buf == NULL)
fd304b
 	{
fd304b
 		fprintf(stderr, "Table is unreachable, sorry."
fd304b
 #ifndef USE_MMAP
fd304b
-- 
fd304b
2.5.0
fd304b