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

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