Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+16 -8
+1 -1
arch/x86/platform/efi/efi.c
··· 206 206 } 207 207 208 208 if (boot_used_size && !finished) { 209 - unsigned long size; 209 + unsigned long size = 0; 210 210 u32 attr; 211 211 efi_status_t s; 212 212 void *tmp;
+3 -5
drivers/firmware/efi/efivars.c
··· 523 523 struct efivar_entry *entry; 524 524 int err; 525 525 526 - entry = kzalloc(sizeof(*entry), GFP_KERNEL); 527 - if (!entry) 528 - return; 529 - 530 526 /* Add new sysfs entries */ 531 527 while (1) { 532 - memset(entry, 0, sizeof(*entry)); 528 + entry = kzalloc(sizeof(*entry), GFP_KERNEL); 529 + if (!entry) 530 + return; 533 531 534 532 err = efivar_init(efivar_update_sysfs_entry, entry, 535 533 true, false, &efivar_sysfs_list);
+12 -2
fs/efivarfs/file.c
··· 44 44 45 45 bytes = efivar_entry_set_get_size(var, attributes, &datasize, 46 46 data, &set); 47 - if (!set && bytes) 47 + if (!set && bytes) { 48 + if (bytes == -ENOENT) 49 + bytes = -EIO; 48 50 goto out; 51 + } 49 52 50 53 if (bytes == -ENOENT) { 51 54 drop_nlink(inode); ··· 79 76 int err; 80 77 81 78 err = efivar_entry_size(var, &datasize); 82 - if (err) 79 + 80 + /* 81 + * efivarfs represents uncommitted variables with 82 + * zero-length files. Reading them should return EOF. 83 + */ 84 + if (err == -ENOENT) 85 + return 0; 86 + else if (err) 83 87 return err; 84 88 85 89 data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL);