mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-29 09:59:01 +00:00
Fix SMBIOS struct parsing when there are three NULs in a row
We need to be careful detecting the end of a string section when the struct ends with NUL NUL NUL. Fixes https://github.com/fwupd/fwupd/issues/5509
This commit is contained in:
parent
d911ca60c5
commit
ae80ba6d16
@ -98,14 +98,21 @@ fu_smbios_setup_from_data(FuSmbios *self, const guint8 *buf, gsize sz, GError **
|
||||
if (!fu_memread_uint16_safe(buf, sz, i + 0x2, &str_handle, G_LITTLE_ENDIAN, error))
|
||||
return FALSE;
|
||||
|
||||
/* invalid */
|
||||
if (str_len == 0x00)
|
||||
break;
|
||||
if (i + str_len >= sz) {
|
||||
g_set_error_literal(error,
|
||||
/* sanity check */
|
||||
if (str_len < 4) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"structure larger than available data");
|
||||
"structure smaller than allowed @0x%x",
|
||||
(guint)i);
|
||||
return FALSE;
|
||||
}
|
||||
if (i + str_len >= sz) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"structure larger than available data @0x%x",
|
||||
(guint)i);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -118,22 +125,21 @@ fu_smbios_setup_from_data(FuSmbios *self, const guint8 *buf, gsize sz, GError **
|
||||
g_byte_array_append(item->buf, buf + i, str_len);
|
||||
g_ptr_array_add(self->items, item);
|
||||
|
||||
/* jump to the end of the struct */
|
||||
/* jump to the end of the formatted area of the struct */
|
||||
i += str_len;
|
||||
if (buf[i] == '\0' && buf[i + 1] == '\0') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* add strings from table */
|
||||
for (gsize start_offset = i; i < sz; i++) {
|
||||
if (buf[i] == '\0') {
|
||||
if (start_offset == i)
|
||||
while (i < sz) {
|
||||
GString *str;
|
||||
|
||||
/* end of string section */
|
||||
if (item->strings->len > 0 && buf[i] == 0x0)
|
||||
break;
|
||||
g_ptr_array_add(item->strings,
|
||||
g_strdup((const gchar *)&buf[start_offset]));
|
||||
start_offset = i + 1;
|
||||
}
|
||||
|
||||
/* copy into string table */
|
||||
str = fu_strdup((const gchar *)buf, sz, i);
|
||||
i += str->len + 1;
|
||||
g_ptr_array_add(item->strings, g_string_free(str, FALSE));
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -171,6 +171,35 @@ fu_strstrip(const gchar *str)
|
||||
return g_strndup(str + head, tail - head + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_strdup:
|
||||
* @str: a string, e.g. ` test `
|
||||
* @bufsz: the maximum size of @str
|
||||
* @offset: the offset to start copying from
|
||||
*
|
||||
* Copies a string from a buffer of a specified size up to (but not including) `NUL`.
|
||||
*
|
||||
* Returns: (transfer full): a #GString, possibly of zero size.
|
||||
*
|
||||
* Since: 1.8.11
|
||||
**/
|
||||
GString *
|
||||
fu_strdup(const gchar *str, gsize bufsz, gsize offset)
|
||||
{
|
||||
GString *substr;
|
||||
|
||||
g_return_val_if_fail(str != NULL, NULL);
|
||||
g_return_val_if_fail(offset < bufsz, NULL);
|
||||
|
||||
substr = g_string_new(NULL);
|
||||
while (offset < bufsz) {
|
||||
if (str[offset] == '\0')
|
||||
break;
|
||||
g_string_append_c(substr, str[offset++]);
|
||||
}
|
||||
return substr;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_string_replace:
|
||||
* @string: the #GString to operate on
|
||||
|
@ -33,6 +33,8 @@ gchar **
|
||||
fu_strsplit(const gchar *str, gsize sz, const gchar *delimiter, gint max_tokens);
|
||||
gchar *
|
||||
fu_strjoin(const gchar *separator, GPtrArray *array);
|
||||
GString *
|
||||
fu_strdup(const gchar *str, gsize bufsz, gsize offset);
|
||||
|
||||
/**
|
||||
* FuStrsplitFunc:
|
||||
|
@ -1165,5 +1165,6 @@ LIBFWUPDPLUGIN_1.8.11 {
|
||||
fu_device_has_problem;
|
||||
fu_device_sleep;
|
||||
fu_device_sleep_full;
|
||||
fu_strdup;
|
||||
local: *;
|
||||
} LIBFWUPDPLUGIN_1.8.10;
|
||||
|
Loading…
Reference in New Issue
Block a user