|
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 |
|