diff options
author | Jeremy Kerr <jeremy.kerr@canonical.com> | 2012-10-19 03:16:45 -0400 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2012-10-30 06:39:25 -0400 |
commit | 310ad75448329f167af3c4a10e4a9de4d80058ff (patch) | |
tree | 1ef1debdf5b974b35e2c06d77f9ad4dd6ecdee1c /drivers/firmware | |
parent | f5f6a60ad52fc786c517303590f1efaea614c69b (diff) |
efi: Clarify GUID length calculations
At present, the handling of GUIDs in efivar file names isn't consistent.
We use GUID_LEN in some places, and 38 in others (GUID_LEN plus
separator), and implicitly use the presence of the trailing NUL.
This change removes the trailing NUL from GUID_LEN, so that we're
explicitly adding it when required. We also replace magic numbers
with GUID_LEN, and clarify the comments where appropriate.
We also fix the allocation size in efivar_create_sysfs_entry, where
we're allocating one byte too much, due to counting the trailing NUL
twice - once when calculating short_name_size, and once in the kzalloc.
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/efivars.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index d478c568ce4f..a93e401c20a7 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -95,7 +95,12 @@ MODULE_LICENSE("GPL"); | |||
95 | MODULE_VERSION(EFIVARS_VERSION); | 95 | MODULE_VERSION(EFIVARS_VERSION); |
96 | 96 | ||
97 | #define DUMP_NAME_LEN 52 | 97 | #define DUMP_NAME_LEN 52 |
98 | #define GUID_LEN 37 | 98 | |
99 | /* | ||
100 | * Length of a GUID string (strlen("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee")) | ||
101 | * not including trailing NUL | ||
102 | */ | ||
103 | #define GUID_LEN 36 | ||
99 | 104 | ||
100 | /* | 105 | /* |
101 | * The maximum size of VariableName + Data = 1024 | 106 | * The maximum size of VariableName + Data = 1024 |
@@ -887,7 +892,11 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, | |||
887 | struct efivar_entry *var; | 892 | struct efivar_entry *var; |
888 | int namelen, i = 0, err = 0; | 893 | int namelen, i = 0, err = 0; |
889 | 894 | ||
890 | if (dentry->d_name.len < 38) | 895 | /* |
896 | * We need a GUID, plus at least one letter for the variable name, | ||
897 | * plus the '-' separator | ||
898 | */ | ||
899 | if (dentry->d_name.len < GUID_LEN + 2) | ||
891 | return -EINVAL; | 900 | return -EINVAL; |
892 | 901 | ||
893 | inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0); | 902 | inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0); |
@@ -900,7 +909,8 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry, | |||
900 | goto out; | 909 | goto out; |
901 | } | 910 | } |
902 | 911 | ||
903 | namelen = dentry->d_name.len - GUID_LEN; | 912 | /* length of the variable name itself: remove GUID and separator */ |
913 | namelen = dentry->d_name.len - GUID_LEN - 1; | ||
904 | 914 | ||
905 | efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1, | 915 | efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1, |
906 | &var->var.VendorGuid); | 916 | &var->var.VendorGuid); |
@@ -994,8 +1004,8 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) | |||
994 | 1004 | ||
995 | len = utf16_strlen(entry->var.VariableName); | 1005 | len = utf16_strlen(entry->var.VariableName); |
996 | 1006 | ||
997 | /* GUID plus trailing NULL */ | 1007 | /* name, plus '-', plus GUID, plus NUL*/ |
998 | name = kmalloc(len + 38, GFP_ATOMIC); | 1008 | name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC); |
999 | if (!name) | 1009 | if (!name) |
1000 | goto fail; | 1010 | goto fail; |
1001 | 1011 | ||
@@ -1006,7 +1016,7 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent) | |||
1006 | 1016 | ||
1007 | efi_guid_unparse(&entry->var.VendorGuid, name + len + 1); | 1017 | efi_guid_unparse(&entry->var.VendorGuid, name + len + 1); |
1008 | 1018 | ||
1009 | name[len+GUID_LEN] = '\0'; | 1019 | name[len+GUID_LEN+1] = '\0'; |
1010 | 1020 | ||
1011 | inode = efivarfs_get_inode(efivarfs_sb, root->d_inode, | 1021 | inode = efivarfs_get_inode(efivarfs_sb, root->d_inode, |
1012 | S_IFREG | 0644, 0); | 1022 | S_IFREG | 0644, 0); |
@@ -1435,11 +1445,18 @@ efivar_create_sysfs_entry(struct efivars *efivars, | |||
1435 | efi_char16_t *variable_name, | 1445 | efi_char16_t *variable_name, |
1436 | efi_guid_t *vendor_guid) | 1446 | efi_guid_t *vendor_guid) |
1437 | { | 1447 | { |
1438 | int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38; | 1448 | int i, short_name_size; |
1439 | char *short_name; | 1449 | char *short_name; |
1440 | struct efivar_entry *new_efivar; | 1450 | struct efivar_entry *new_efivar; |
1441 | 1451 | ||
1442 | short_name = kzalloc(short_name_size + 1, GFP_KERNEL); | 1452 | /* |
1453 | * Length of the variable bytes in ASCII, plus the '-' separator, | ||
1454 | * plus the GUID, plus trailing NUL | ||
1455 | */ | ||
1456 | short_name_size = variable_name_size / sizeof(efi_char16_t) | ||
1457 | + 1 + GUID_LEN + 1; | ||
1458 | |||
1459 | short_name = kzalloc(short_name_size, GFP_KERNEL); | ||
1443 | new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); | 1460 | new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); |
1444 | 1461 | ||
1445 | if (!short_name || !new_efivar) { | 1462 | if (!short_name || !new_efivar) { |