|
@@ -1705,6 +1705,31 @@ static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
|
|
|
return found;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Returns the size of variable_name, in bytes, including the
|
|
|
+ * terminating NULL character, or variable_name_size if no NULL
|
|
|
+ * character is found among the first variable_name_size bytes.
|
|
|
+ */
|
|
|
+static unsigned long var_name_strnsize(efi_char16_t *variable_name,
|
|
|
+ unsigned long variable_name_size)
|
|
|
+{
|
|
|
+ unsigned long len;
|
|
|
+ efi_char16_t c;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The variable name is, by definition, a NULL-terminated
|
|
|
+ * string, so make absolutely sure that variable_name_size is
|
|
|
+ * the value we expect it to be. If not, return the real size.
|
|
|
+ */
|
|
|
+ for (len = 2; len <= variable_name_size; len += sizeof(c)) {
|
|
|
+ c = variable_name[(len / sizeof(c)) - 1];
|
|
|
+ if (!c)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return min(len, variable_name_size);
|
|
|
+}
|
|
|
+
|
|
|
static void efivar_update_sysfs_entries(struct work_struct *work)
|
|
|
{
|
|
|
struct efivars *efivars = &__efivars;
|
|
@@ -1745,10 +1770,13 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
|
|
|
if (!found) {
|
|
|
kfree(variable_name);
|
|
|
break;
|
|
|
- } else
|
|
|
+ } else {
|
|
|
+ variable_name_size = var_name_strnsize(variable_name,
|
|
|
+ variable_name_size);
|
|
|
efivar_create_sysfs_entry(efivars,
|
|
|
variable_name_size,
|
|
|
variable_name, &vendor);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1995,6 +2023,8 @@ int register_efivars(struct efivars *efivars,
|
|
|
&vendor_guid);
|
|
|
switch (status) {
|
|
|
case EFI_SUCCESS:
|
|
|
+ variable_name_size = var_name_strnsize(variable_name,
|
|
|
+ variable_name_size);
|
|
|
efivar_create_sysfs_entry(efivars,
|
|
|
variable_name_size,
|
|
|
variable_name,
|