diff options
Diffstat (limited to 'user/dmidecode/security2.patch')
-rw-r--r-- | user/dmidecode/security2.patch | 98 |
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 + |