Blame 0020-dmidecode-Validate-structure-completeness-before-dec.patch

Anton Arapov c2a608
From 4cbba9a8e76ffc640eaf7dd25acbd3c1c6504669 Mon Sep 17 00:00:00 2001
Anton Arapov c2a608
From: Jean Delvare <jdelvare@suse.de>
Anton Arapov c2a608
Date: Wed, 1 Aug 2018 09:54:51 +0200
Anton Arapov c2a608
Subject: [PATCH 20/21] dmidecode: Validate structure completeness before
Anton Arapov c2a608
 decoding
Anton Arapov c2a608
Anton Arapov c2a608
Ensure that the whole DMI structure fits in the announced table
Anton Arapov c2a608
length before performing any action on it. Otherwise we might end up
Anton Arapov c2a608
reading beyond the end of our memory buffer.
Anton Arapov c2a608
Anton Arapov c2a608
This bug was discovered by Lionel Debroux using the AFL fuzzer and
Anton Arapov c2a608
AddressSanitizer. Its probability is very low, as it requires a DMI
Anton Arapov c2a608
table corrupted in one of two very specific ways to trigger.
Anton Arapov c2a608
Anton Arapov c2a608
This bug exists since dmidecode version 2.9, although it is hard to
Anton Arapov c2a608
test because option --from-dump was only introduced in version 2.10.
Anton Arapov c2a608
Anton Arapov c2a608
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Anton Arapov c2a608
---
Anton Arapov c2a608
 dmidecode.c | 39 ++++++++++++++++++++++-----------------
Anton Arapov c2a608
 1 file changed, 22 insertions(+), 17 deletions(-)
Anton Arapov c2a608
Anton Arapov c2a608
diff --git a/dmidecode.c b/dmidecode.c
Anton Arapov c2a608
index 474ca7b..76faed9 100644
Anton Arapov c2a608
--- a/dmidecode.c
Anton Arapov c2a608
+++ b/dmidecode.c
Anton Arapov c2a608
@@ -4754,6 +4754,7 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
Anton Arapov c2a608
 			}
Anton Arapov c2a608
 			break;
Anton Arapov c2a608
 		}
Anton Arapov c2a608
+		i++;
Anton Arapov c2a608
 
Anton Arapov c2a608
 		/* In quiet mode, stop decoding at end of table marker */
Anton Arapov c2a608
 		if ((opt.flags & FLAG_QUIET) && h.type == 127)
Anton Arapov c2a608
@@ -4764,6 +4765,22 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
Anton Arapov c2a608
 			printf("Handle 0x%04X, DMI type %d, %d bytes\n",
Anton Arapov c2a608
 				h.handle, h.type, h.length);
Anton Arapov c2a608
 
Anton Arapov c2a608
+		/* Look for the next handle */
Anton Arapov c2a608
+		next = data + h.length;
Anton Arapov c2a608
+		while ((unsigned long)(next - buf + 1) < len
Anton Arapov c2a608
+		    && (next[0] != 0 || next[1] != 0))
Anton Arapov c2a608
+			next++;
Anton Arapov c2a608
+		next += 2;
Anton Arapov c2a608
+
Anton Arapov c2a608
+		/* Make sure the whole structure fits in the table */
Anton Arapov c2a608
+		if ((unsigned long)(next - buf) > len)
Anton Arapov c2a608
+		{
Anton Arapov c2a608
+			if (display && !(opt.flags & FLAG_QUIET))
Anton Arapov c2a608
+				printf("\t<TRUNCATED>\n\n");
Anton Arapov c2a608
+			data = next;
Anton Arapov c2a608
+			break;
Anton Arapov c2a608
+		}
Anton Arapov c2a608
+
Anton Arapov c2a608
 		/* assign vendor for vendor-specific decodes later */
Anton Arapov c2a608
 		if (h.type == 1 && h.length >= 5)
Anton Arapov c2a608
 			dmi_set_vendor(dmi_string(&h, data[0x04]));
Anton Arapov c2a608
@@ -4772,33 +4789,21 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
Anton Arapov c2a608
 		if (h.type == 34)
Anton Arapov c2a608
 			dmi_fixup_type_34(&h, display);
Anton Arapov c2a608
 
Anton Arapov c2a608
-		/* look for the next handle */
Anton Arapov c2a608
-		next = data + h.length;
Anton Arapov c2a608
-		while ((unsigned long)(next - buf + 1) < len
Anton Arapov c2a608
-		    && (next[0] != 0 || next[1] != 0))
Anton Arapov c2a608
-			next++;
Anton Arapov c2a608
-		next += 2;
Anton Arapov c2a608
 		if (display)
Anton Arapov c2a608
 		{
Anton Arapov c2a608
-			if ((unsigned long)(next - buf) <= len)
Anton Arapov c2a608
+			if (opt.flags & FLAG_DUMP)
Anton Arapov c2a608
 			{
Anton Arapov c2a608
-				if (opt.flags & FLAG_DUMP)
Anton Arapov c2a608
-				{
Anton Arapov c2a608
-					dmi_dump(&h, "\t");
Anton Arapov c2a608
-					printf("\n");
Anton Arapov c2a608
-				}
Anton Arapov c2a608
-				else
Anton Arapov c2a608
-					dmi_decode(&h, ver);
Anton Arapov c2a608
+				dmi_dump(&h, "\t");
Anton Arapov c2a608
+				printf("\n");
Anton Arapov c2a608
 			}
Anton Arapov c2a608
-			else if (!(opt.flags & FLAG_QUIET))
Anton Arapov c2a608
-				printf("\t<TRUNCATED>\n\n");
Anton Arapov c2a608
+			else
Anton Arapov c2a608
+				dmi_decode(&h, ver);
Anton Arapov c2a608
 		}
Anton Arapov c2a608
 		else if (opt.string != NULL
Anton Arapov c2a608
 		      && opt.string->type == h.type)
Anton Arapov c2a608
 			dmi_table_string(&h, data, ver);
Anton Arapov c2a608
 
Anton Arapov c2a608
 		data = next;
Anton Arapov c2a608
-		i++;
Anton Arapov c2a608
 
Anton Arapov c2a608
 		/* SMBIOS v3 requires stopping at this marker */
Anton Arapov c2a608
 		if (h.type == 127 && (flags & FLAG_STOP_AT_EOT))
Anton Arapov c2a608
-- 
Anton Arapov c2a608
2.17.1
Anton Arapov c2a608