aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorAndy Whitcroft <apw@canonical.com>2012-10-11 06:32:21 -0400
committerMatt Fleming <matt.fleming@intel.com>2012-10-30 06:39:23 -0400
commit5ba6e2919b9e18a051e5bdd6c21f52ee4976513f (patch)
tree3596645096f15d3b9423fa67cc3421f3f72458cd /drivers/firmware
parentc0359db1a1c484ea810f4d5a877d3b00d107908b (diff)
efivarfs: efivarfs_fill_super() ensure we clean up correctly on error
Ensure we free both the name and inode on error when building the individual variables. Signed-off-by: Andy Whitcroft <apw@canonical.com> Acked-by: Matthew Garrett <mjg@redhat.com> Acked-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.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 36b3dd6e1e5e..216086d88380 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -948,6 +948,7 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
948 struct dentry *root; 948 struct dentry *root;
949 struct efivar_entry *entry, *n; 949 struct efivar_entry *entry, *n;
950 struct efivars *efivars = &__efivars; 950 struct efivars *efivars = &__efivars;
951 char *name;
951 952
952 efivarfs_sb = sb; 953 efivarfs_sb = sb;
953 954
@@ -969,16 +970,18 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
969 return -ENOMEM; 970 return -ENOMEM;
970 971
971 list_for_each_entry_safe(entry, n, &efivars->list, list) { 972 list_for_each_entry_safe(entry, n, &efivars->list, list) {
972 struct inode *inode;
973 struct dentry *dentry, *root = efivarfs_sb->s_root; 973 struct dentry *dentry, *root = efivarfs_sb->s_root;
974 char *name;
975 unsigned long size = 0; 974 unsigned long size = 0;
976 int len, i; 975 int len, i;
977 976
977 inode = NULL;
978
978 len = utf16_strlen(entry->var.VariableName); 979 len = utf16_strlen(entry->var.VariableName);
979 980
980 /* GUID plus trailing NULL */ 981 /* GUID plus trailing NULL */
981 name = kmalloc(len + 38, GFP_ATOMIC); 982 name = kmalloc(len + 38, GFP_ATOMIC);
983 if (!name)
984 goto fail;
982 985
983 for (i = 0; i < len; i++) 986 for (i = 0; i < len; i++)
984 name[i] = entry->var.VariableName[i] & 0xFF; 987 name[i] = entry->var.VariableName[i] & 0xFF;
@@ -991,7 +994,13 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
991 994
992 inode = efivarfs_get_inode(efivarfs_sb, root->d_inode, 995 inode = efivarfs_get_inode(efivarfs_sb, root->d_inode,
993 S_IFREG | 0644, 0); 996 S_IFREG | 0644, 0);
997 if (!inode)
998 goto fail_name;
999
994 dentry = d_alloc_name(root, name); 1000 dentry = d_alloc_name(root, name);
1001 if (!dentry)
1002 goto fail_inode;
1003
995 /* copied by the above to local storage in the dentry. */ 1004 /* copied by the above to local storage in the dentry. */
996 kfree(name); 1005 kfree(name);
997 1006
@@ -1009,6 +1018,13 @@ int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
1009 } 1018 }
1010 1019
1011 return 0; 1020 return 0;
1021
1022fail_inode:
1023 iput(inode);
1024fail_name:
1025 kfree(name);
1026fail:
1027 return -ENOMEM;
1012} 1028}
1013 1029
1014static struct dentry *efivarfs_mount(struct file_system_type *fs_type, 1030static struct dentry *efivarfs_mount(struct file_system_type *fs_type,