aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-03-05 07:46:30 -0500
committerMatt Fleming <matt.fleming@intel.com>2013-03-06 09:46:30 -0500
commitfeff5dc4f98330d8152b521acc2e18c16712e6c8 (patch)
tree9d4180eb62dcb4f1d111acc3c1e000e82c80b1f6
parent123abd76edf56c02a76b46d3d673897177ef067b (diff)
efivarfs: return accurate error code in efivarfs_fill_super()
Joseph was hitting a failure case when mounting efivarfs which resulted in an incorrect error message, $ sudo mount -v /sys/firmware/efi/efivars mount: Cannot allocate memory triggered when efivarfs_valid_name() returned -EINVAL. Make sure we pass accurate return values up the stack if efivarfs_fill_super() fails to build inodes for EFI variables. Reported-by: Joseph Yasi <joe.yasi@gmail.com> Reported-by: Lingzhu Xiang <lxiang@redhat.com> Cc: Josh Boyer <jwboyer@redhat.com> Cc: Jeremy Kerr <jk@ozlabs.org> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: <stable@vger.kernel.org> # v3.8 Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--drivers/firmware/efivars.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 1b9a6e17e3dc..bea32d1ef7d5 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -1163,15 +1163,22 @@ static struct dentry_operations efivarfs_d_ops = {
1163 1163
1164static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name) 1164static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
1165{ 1165{
1166 struct dentry *d;
1166 struct qstr q; 1167 struct qstr q;
1168 int err;
1167 1169
1168 q.name = name; 1170 q.name = name;
1169 q.len = strlen(name); 1171 q.len = strlen(name);
1170 1172
1171 if (efivarfs_d_hash(NULL, NULL, &q)) 1173 err = efivarfs_d_hash(NULL, NULL, &q);
1172 return NULL; 1174 if (err)
1175 return ERR_PTR(err);
1176
1177 d = d_alloc(parent, &q);
1178 if (d)
1179 return d;
1173 1180
1174 return d_alloc(parent, &q); 1181 return ERR_PTR(-ENOMEM);
1175} 1182}
1176 1183
1177static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) 1184static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
@@ -1181,6 +1188,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
1181 struct efivar_entry *entry, *n; 1188 struct efivar_entry *entry, *n;
1182 struct efivars *efivars = &__efivars; 1189 struct efivars *efivars = &__efivars;
1183 char *name; 1190 char *name;
1191 int err = -ENOMEM;
1184 1192
1185 efivarfs_sb = sb; 1193 efivarfs_sb = sb;
1186 1194
@@ -1231,8 +1239,10 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
1231 goto fail_name; 1239 goto fail_name;
1232 1240
1233 dentry = efivarfs_alloc_dentry(root, name); 1241 dentry = efivarfs_alloc_dentry(root, name);
1234 if (!dentry) 1242 if (IS_ERR(dentry)) {
1243 err = PTR_ERR(dentry);
1235 goto fail_inode; 1244 goto fail_inode;
1245 }
1236 1246
1237 /* copied by the above to local storage in the dentry. */ 1247 /* copied by the above to local storage in the dentry. */
1238 kfree(name); 1248 kfree(name);
@@ -1259,7 +1269,7 @@ fail_inode:
1259fail_name: 1269fail_name:
1260 kfree(name); 1270 kfree(name);
1261fail: 1271fail:
1262 return -ENOMEM; 1272 return err;
1263} 1273}
1264 1274
1265static struct dentry *efivarfs_mount(struct file_system_type *fs_type, 1275static struct dentry *efivarfs_mount(struct file_system_type *fs_type,