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