diff options
author | Jean Delvare <jdelvare@suse.de> | 2018-02-03 05:25:20 -0500 |
---|---|---|
committer | Jean Delvare <jdelvare@suse.de> | 2018-02-03 05:25:20 -0500 |
commit | a7770ae194569e96a93c48aceb304edded9cc648 (patch) | |
tree | 90cb465ea86fb1f3c455b90e1f71739511bb735a | |
parent | 7117794feb1602ea5efca1c7bfd5b78c3278d29d (diff) |
firmware: dmi_scan: Fix handling of empty DMI strings
The handling of empty DMI strings looks quite broken to me:
* Strings from 1 to 7 spaces are not considered empty.
* True empty DMI strings (string index set to 0) are not considered
empty, and result in allocating a 0-char string.
* Strings with invalid index also result in allocating a 0-char
string.
* Strings starting with 8 spaces are all considered empty, even if
non-space characters follow (sounds like a weird thing to do, but
I have actually seen occurrences of this in DMI tables before.)
* Strings which are considered empty are reported as 8 spaces,
instead of being actually empty.
Some of these issues are the result of an off-by-one error in memcmp,
the rest is incorrect by design.
So let's get it square: missing strings and strings made of only
spaces, regardless of their length, should be treated as empty and
no memory should be allocated for them. All other strings are
non-empty and should be allocated.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Fixes: 79da4721117f ("x86: fix DMI out of memory problems")
Cc: Parag Warudkar <parag.warudkar@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | drivers/firmware/dmi_scan.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 8cd5db6691b2..a7072e7880ee 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -18,7 +18,7 @@ EXPORT_SYMBOL_GPL(dmi_kobj); | |||
18 | * of and an antecedent to, SMBIOS, which stands for System | 18 | * of and an antecedent to, SMBIOS, which stands for System |
19 | * Management BIOS. See further: http://www.dmtf.org/standards | 19 | * Management BIOS. See further: http://www.dmtf.org/standards |
20 | */ | 20 | */ |
21 | static const char dmi_empty_string[] = " "; | 21 | static const char dmi_empty_string[] = ""; |
22 | 22 | ||
23 | static u32 dmi_ver __initdata; | 23 | static u32 dmi_ver __initdata; |
24 | static u32 dmi_len; | 24 | static u32 dmi_len; |
@@ -39,25 +39,21 @@ static int dmi_memdev_nr; | |||
39 | static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s) | 39 | static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s) |
40 | { | 40 | { |
41 | const u8 *bp = ((u8 *) dm) + dm->length; | 41 | const u8 *bp = ((u8 *) dm) + dm->length; |
42 | const u8 *nsp; | ||
42 | 43 | ||
43 | if (s) { | 44 | if (s) { |
44 | s--; | 45 | while (--s > 0 && *bp) |
45 | while (s > 0 && *bp) { | ||
46 | bp += strlen(bp) + 1; | 46 | bp += strlen(bp) + 1; |
47 | s--; | ||
48 | } | ||
49 | |||
50 | if (*bp != 0) { | ||
51 | size_t len = strlen(bp)+1; | ||
52 | size_t cmp_len = len > 8 ? 8 : len; | ||
53 | 47 | ||
54 | if (!memcmp(bp, dmi_empty_string, cmp_len)) | 48 | /* Strings containing only spaces are considered empty */ |
55 | return dmi_empty_string; | 49 | nsp = bp; |
50 | while (*nsp == ' ') | ||
51 | nsp++; | ||
52 | if (*nsp != '\0') | ||
56 | return bp; | 53 | return bp; |
57 | } | ||
58 | } | 54 | } |
59 | 55 | ||
60 | return ""; | 56 | return dmi_empty_string; |
61 | } | 57 | } |
62 | 58 | ||
63 | static const char * __init dmi_string(const struct dmi_header *dm, u8 s) | 59 | static const char * __init dmi_string(const struct dmi_header *dm, u8 s) |