efivarfs: add helper to convert from UC16 name and GUID to utf8 name

These will be used by a later patch to check for uniqueness on initial
EFI variable iteration.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
James Bottomley 2025-01-06 18:35:21 -08:00 committed by Ard Biesheuvel
parent c57b6e1d8a
commit 1aba87f92d
3 changed files with 29 additions and 14 deletions

View File

@ -55,6 +55,7 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
unsigned long data_size);
bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
size_t len);
char *efivar_get_utf8name(const efi_char16_t *name16, efi_guid_t *vendor);
extern const struct file_operations efivarfs_file_operations;
extern const struct inode_operations efivarfs_dir_inode_operations;

View File

@ -205,27 +205,16 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
memcpy(entry->var.VariableName, name16, name_size);
memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
len = ucs2_utf8size(entry->var.VariableName);
/* name, plus '-', plus GUID, plus NUL*/
name = kmalloc(len + 1 + EFI_VARIABLE_GUID_LEN + 1, GFP_KERNEL);
name = efivar_get_utf8name(name16, &vendor);
if (!name)
goto fail;
ucs2_as_utf8(name, entry->var.VariableName, len);
/* length of the variable name itself: remove GUID and separator */
len = strlen(name) - EFI_VARIABLE_GUID_LEN - 1;
if (efivar_variable_is_removable(entry->var.VendorGuid, name, len))
is_removable = true;
name[len] = '-';
efi_guid_to_str(&entry->var.VendorGuid, name + len + 1);
name[len + EFI_VARIABLE_GUID_LEN+1] = '\0';
/* replace invalid slashes like kobject_set_name_vargs does for /sys/firmware/efi/vars. */
strreplace(name, '/', '!');
inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0,
is_removable);
if (!inode)

View File

@ -225,6 +225,31 @@ variable_matches(const char *var_name, size_t len, const char *match_name,
}
}
char *
efivar_get_utf8name(const efi_char16_t *name16, efi_guid_t *vendor)
{
int len = ucs2_utf8size(name16);
char *name;
/* name, plus '-', plus GUID, plus NUL*/
name = kmalloc(len + 1 + EFI_VARIABLE_GUID_LEN + 1, GFP_KERNEL);
if (!name)
return NULL;
ucs2_as_utf8(name, name16, len);
name[len] = '-';
efi_guid_to_str(vendor, name + len + 1);
name[len + EFI_VARIABLE_GUID_LEN+1] = '\0';
/* replace invalid slashes like kobject_set_name_vargs does for /sys/firmware/efi/vars. */
strreplace(name, '/', '!');
return name;
}
bool
efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
unsigned long data_size)