Ensure DMI strings used in dmi_compare() are not NULL
Previously the external DMI decoder did not allow this to happen because
all possible pointers were initialized at startup by the output of
'dmidecode -s ...' which has default values for all supported types.
The now active internal DMI decoder does work differently: it scans the
complete DMI table once and copies the available strings. Therefore, strings
that are not set by the firmware are left at their default value of NULL.
A segfault would arise if the following conditions are all true:
- the firmware sets up a DMI/SMBIOS table which has at least a correct
checksum, and
- that table does *not* define at least one of the DMI strings we use
for matching (as defined by dmi_strings[] in dmi.c), and
- there exists a board enable whose PCI IDs are matched by the board,
and which has a DMI string set that ends with a $ anchor, and
- the user calls the internal programmer of flashrom without the
optional mainboard parameter.
This was first observed by Gelip on an abit BF6 using the coreboot port
for the abit BE6-II V2.0.
The segfault was reproduced by Idwer Vollering on an ASUS F2A85-M with
the default DMI values of CONFIG_MAINBOARD_SMBIOS_MANUFACTURER etc.
overwritten and a forged board enable matching his board.
Idwer also verified that this patch fixes the problem, thanks a lot!
Corresponding to flashrom svn r1763.
Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
diff --git a/dmi.c b/dmi.c
index 14f3871..ef7ae2c 100644
--- a/dmi.c
+++ b/dmi.c
@@ -406,8 +406,8 @@
* at the beginning and '$' at the end. So you can look for "^prefix",
* "suffix$", "substring" or "^complete string$".
*
- * @param value The string to check.
- * @param pattern The pattern.
+ * @param value The non-NULL string to check.
+ * @param pattern The non-NULL pattern.
* @return Nonzero if pattern matches.
*/
static int dmi_compare(const char *value, const char *pattern)
@@ -454,9 +454,13 @@
if (!has_dmi_support)
return 0;
- for (i = 0; i < ARRAY_SIZE(dmi_strings); i++)
+ for (i = 0; i < ARRAY_SIZE(dmi_strings); i++) {
+ if (dmi_strings[i].value == NULL)
+ continue;
+
if (dmi_compare(dmi_strings[i].value, pattern))
return 1;
+ }
return 0;
}