diff options
-rw-r--r-- | drivers/firmware/efivars.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 6607daf5a08d..1e9d9b9d7a12 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -1705,6 +1705,31 @@ static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor) | |||
1705 | return found; | 1705 | return found; |
1706 | } | 1706 | } |
1707 | 1707 | ||
1708 | /* | ||
1709 | * Returns the size of variable_name, in bytes, including the | ||
1710 | * terminating NULL character, or variable_name_size if no NULL | ||
1711 | * character is found among the first variable_name_size bytes. | ||
1712 | */ | ||
1713 | static unsigned long var_name_strnsize(efi_char16_t *variable_name, | ||
1714 | unsigned long variable_name_size) | ||
1715 | { | ||
1716 | unsigned long len; | ||
1717 | efi_char16_t c; | ||
1718 | |||
1719 | /* | ||
1720 | * The variable name is, by definition, a NULL-terminated | ||
1721 | * string, so make absolutely sure that variable_name_size is | ||
1722 | * the value we expect it to be. If not, return the real size. | ||
1723 | */ | ||
1724 | for (len = 2; len <= variable_name_size; len += sizeof(c)) { | ||
1725 | c = variable_name[(len / sizeof(c)) - 1]; | ||
1726 | if (!c) | ||
1727 | break; | ||
1728 | } | ||
1729 | |||
1730 | return min(len, variable_name_size); | ||
1731 | } | ||
1732 | |||
1708 | static void efivar_update_sysfs_entries(struct work_struct *work) | 1733 | static void efivar_update_sysfs_entries(struct work_struct *work) |
1709 | { | 1734 | { |
1710 | struct efivars *efivars = &__efivars; | 1735 | struct efivars *efivars = &__efivars; |
@@ -1745,10 +1770,13 @@ static void efivar_update_sysfs_entries(struct work_struct *work) | |||
1745 | if (!found) { | 1770 | if (!found) { |
1746 | kfree(variable_name); | 1771 | kfree(variable_name); |
1747 | break; | 1772 | break; |
1748 | } else | 1773 | } else { |
1774 | variable_name_size = var_name_strnsize(variable_name, | ||
1775 | variable_name_size); | ||
1749 | efivar_create_sysfs_entry(efivars, | 1776 | efivar_create_sysfs_entry(efivars, |
1750 | variable_name_size, | 1777 | variable_name_size, |
1751 | variable_name, &vendor); | 1778 | variable_name, &vendor); |
1779 | } | ||
1752 | } | 1780 | } |
1753 | } | 1781 | } |
1754 | 1782 | ||
@@ -1995,6 +2023,8 @@ int register_efivars(struct efivars *efivars, | |||
1995 | &vendor_guid); | 2023 | &vendor_guid); |
1996 | switch (status) { | 2024 | switch (status) { |
1997 | case EFI_SUCCESS: | 2025 | case EFI_SUCCESS: |
2026 | variable_name_size = var_name_strnsize(variable_name, | ||
2027 | variable_name_size); | ||
1998 | efivar_create_sysfs_entry(efivars, | 2028 | efivar_create_sysfs_entry(efivars, |
1999 | variable_name_size, | 2029 | variable_name_size, |
2000 | variable_name, | 2030 | variable_name, |