Browse Source

Merge tag 'efi-urgent' into x86/urgent

 * Avoid confusing the user by returning -EIO instead of -ENOENT in
   efivarfs if an EFI variable gets deleted from under us and return EOF
   when reading from a zero-length file - Lingzhu Xiang

 * Fix an oops in efivar_update_sysfs_entries() caused by reusing (and
   therefore corrupting) a kzalloc() allocation - Seiji Aguchi

 * Initialise the DataSize argument to GetVariable() otherwise it will
   not be updated with the actual size of the variable on return.
   Discovered on a Acer Aspire V3 BIOS - Lee, Chun-Yi

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
H. Peter Anvin 12 years ago
parent
commit
3979fdce77
3 changed files with 16 additions and 8 deletions
  1. 1 1
      arch/x86/platform/efi/efi.c
  2. 3 5
      drivers/firmware/efi/efivars.c
  3. 12 2
      fs/efivarfs/file.c

+ 1 - 1
arch/x86/platform/efi/efi.c

@@ -206,7 +206,7 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
 	}
 
 	if (boot_used_size && !finished) {
-		unsigned long size;
+		unsigned long size = 0;
 		u32 attr;
 		efi_status_t s;
 		void *tmp;

+ 3 - 5
drivers/firmware/efi/efivars.c

@@ -523,13 +523,11 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
 	struct efivar_entry *entry;
 	int err;
 
-	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
-	if (!entry)
-		return;
-
 	/* Add new sysfs entries */
 	while (1) {
-		memset(entry, 0, sizeof(*entry));
+		entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+		if (!entry)
+			return;
 
 		err = efivar_init(efivar_update_sysfs_entry, entry,
 				  true, false, &efivar_sysfs_list);

+ 12 - 2
fs/efivarfs/file.c

@@ -44,8 +44,11 @@ static ssize_t efivarfs_file_write(struct file *file,
 
 	bytes = efivar_entry_set_get_size(var, attributes, &datasize,
 					  data, &set);
-	if (!set && bytes)
+	if (!set && bytes) {
+		if (bytes == -ENOENT)
+			bytes = -EIO;
 		goto out;
+	}
 
 	if (bytes == -ENOENT) {
 		drop_nlink(inode);
@@ -76,7 +79,14 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
 	int err;
 
 	err = efivar_entry_size(var, &datasize);
-	if (err)
+
+	/*
+	 * efivarfs represents uncommitted variables with
+	 * zero-length files. Reading them should return EOF.
+	 */
+	if (err == -ENOENT)
+		return 0;
+	else if (err)
 		return err;
 
 	data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL);