diff options
Diffstat (limited to 'drivers/firmware/efi/vars.c')
-rw-r--r-- | drivers/firmware/efi/vars.c | 37 |
1 files changed, 13 insertions, 24 deletions
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index dd1c20a426fa..1d80c1ca39c5 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/device.h> | 32 | #include <linux/device.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/ctype.h> | 34 | #include <linux/ctype.h> |
35 | #include <linux/ucs2_string.h> | ||
35 | 36 | ||
36 | /* Private pointer to registered efivars */ | 37 | /* Private pointer to registered efivars */ |
37 | static struct efivars *__efivars; | 38 | static struct efivars *__efivars; |
@@ -91,7 +92,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, | |||
91 | u16 filepathlength; | 92 | u16 filepathlength; |
92 | int i, desclength = 0, namelen; | 93 | int i, desclength = 0, namelen; |
93 | 94 | ||
94 | namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); | 95 | namelen = ucs2_strnlen(var->VariableName, sizeof(var->VariableName)); |
95 | 96 | ||
96 | /* Either "Boot" or "Driver" followed by four digits of hex */ | 97 | /* Either "Boot" or "Driver" followed by four digits of hex */ |
97 | for (i = match; i < match+4; i++) { | 98 | for (i = match; i < match+4; i++) { |
@@ -114,7 +115,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, | |||
114 | * There's no stored length for the description, so it has to be | 115 | * There's no stored length for the description, so it has to be |
115 | * found by hand | 116 | * found by hand |
116 | */ | 117 | */ |
117 | desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; | 118 | desclength = ucs2_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; |
118 | 119 | ||
119 | /* Each boot entry must have a descriptor */ | 120 | /* Each boot entry must have a descriptor */ |
120 | if (!desclength) | 121 | if (!desclength) |
@@ -228,24 +229,12 @@ EXPORT_SYMBOL_GPL(efivar_validate); | |||
228 | static efi_status_t | 229 | static efi_status_t |
229 | check_var_size(u32 attributes, unsigned long size) | 230 | check_var_size(u32 attributes, unsigned long size) |
230 | { | 231 | { |
231 | u64 storage_size, remaining_size, max_size; | ||
232 | efi_status_t status; | ||
233 | const struct efivar_operations *fops = __efivars->ops; | 232 | const struct efivar_operations *fops = __efivars->ops; |
234 | 233 | ||
235 | if (!fops->query_variable_info) | 234 | if (!fops->query_variable_store) |
236 | return EFI_UNSUPPORTED; | 235 | return EFI_UNSUPPORTED; |
237 | 236 | ||
238 | status = fops->query_variable_info(attributes, &storage_size, | 237 | return fops->query_variable_store(attributes, size); |
239 | &remaining_size, &max_size); | ||
240 | |||
241 | if (status != EFI_SUCCESS) | ||
242 | return status; | ||
243 | |||
244 | if (!storage_size || size > remaining_size || size > max_size || | ||
245 | (remaining_size - size) < (storage_size / 2)) | ||
246 | return EFI_OUT_OF_RESOURCES; | ||
247 | |||
248 | return status; | ||
249 | } | 238 | } |
250 | 239 | ||
251 | static int efi_status_to_err(efi_status_t status) | 240 | static int efi_status_to_err(efi_status_t status) |
@@ -288,9 +277,9 @@ static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor, | |||
288 | unsigned long strsize1, strsize2; | 277 | unsigned long strsize1, strsize2; |
289 | bool found = false; | 278 | bool found = false; |
290 | 279 | ||
291 | strsize1 = utf16_strsize(variable_name, 1024); | 280 | strsize1 = ucs2_strsize(variable_name, 1024); |
292 | list_for_each_entry_safe(entry, n, head, list) { | 281 | list_for_each_entry_safe(entry, n, head, list) { |
293 | strsize2 = utf16_strsize(entry->var.VariableName, 1024); | 282 | strsize2 = ucs2_strsize(entry->var.VariableName, 1024); |
294 | if (strsize1 == strsize2 && | 283 | if (strsize1 == strsize2 && |
295 | !memcmp(variable_name, &(entry->var.VariableName), | 284 | !memcmp(variable_name, &(entry->var.VariableName), |
296 | strsize2) && | 285 | strsize2) && |
@@ -594,7 +583,7 @@ int efivar_entry_set(struct efivar_entry *entry, u32 attributes, | |||
594 | return -EEXIST; | 583 | return -EEXIST; |
595 | } | 584 | } |
596 | 585 | ||
597 | status = check_var_size(attributes, size + utf16_strsize(name, 1024)); | 586 | status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); |
598 | if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED) | 587 | if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED) |
599 | status = ops->set_variable(name, &vendor, | 588 | status = ops->set_variable(name, &vendor, |
600 | attributes, size, data); | 589 | attributes, size, data); |
@@ -630,7 +619,7 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, | |||
630 | unsigned long flags; | 619 | unsigned long flags; |
631 | efi_status_t status; | 620 | efi_status_t status; |
632 | 621 | ||
633 | if (!ops->query_variable_info) | 622 | if (!ops->query_variable_store) |
634 | return -ENOSYS; | 623 | return -ENOSYS; |
635 | 624 | ||
636 | if (!block && spin_trylock_irqsave(&__efivars->lock, flags)) | 625 | if (!block && spin_trylock_irqsave(&__efivars->lock, flags)) |
@@ -638,7 +627,7 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, | |||
638 | else | 627 | else |
639 | spin_lock_irqsave(&__efivars->lock, flags); | 628 | spin_lock_irqsave(&__efivars->lock, flags); |
640 | 629 | ||
641 | status = check_var_size(attributes, size + utf16_strsize(name, 1024)); | 630 | status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); |
642 | if (status != EFI_SUCCESS) { | 631 | if (status != EFI_SUCCESS) { |
643 | spin_unlock_irqrestore(&__efivars->lock, flags); | 632 | spin_unlock_irqrestore(&__efivars->lock, flags); |
644 | return -ENOSPC; | 633 | return -ENOSPC; |
@@ -679,8 +668,8 @@ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid, | |||
679 | WARN_ON(!spin_is_locked(&__efivars->lock)); | 668 | WARN_ON(!spin_is_locked(&__efivars->lock)); |
680 | 669 | ||
681 | list_for_each_entry_safe(entry, n, head, list) { | 670 | list_for_each_entry_safe(entry, n, head, list) { |
682 | strsize1 = utf16_strsize(name, 1024); | 671 | strsize1 = ucs2_strsize(name, 1024); |
683 | strsize2 = utf16_strsize(entry->var.VariableName, 1024); | 672 | strsize2 = ucs2_strsize(entry->var.VariableName, 1024); |
684 | if (strsize1 == strsize2 && | 673 | if (strsize1 == strsize2 && |
685 | !memcmp(name, &(entry->var.VariableName), strsize1) && | 674 | !memcmp(name, &(entry->var.VariableName), strsize1) && |
686 | !efi_guidcmp(guid, entry->var.VendorGuid)) { | 675 | !efi_guidcmp(guid, entry->var.VendorGuid)) { |
@@ -818,7 +807,7 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, | |||
818 | /* | 807 | /* |
819 | * Ensure that the available space hasn't shrunk below the safe level | 808 | * Ensure that the available space hasn't shrunk below the safe level |
820 | */ | 809 | */ |
821 | status = check_var_size(attributes, *size + utf16_strsize(name, 1024)); | 810 | status = check_var_size(attributes, *size + ucs2_strsize(name, 1024)); |
822 | if (status != EFI_SUCCESS) { | 811 | if (status != EFI_SUCCESS) { |
823 | if (status != EFI_UNSUPPORTED) { | 812 | if (status != EFI_UNSUPPORTED) { |
824 | err = efi_status_to_err(status); | 813 | err = efi_status_to_err(status); |