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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'efi-urgent-2020-03-15' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull EFI fixes from Thomas Gleixner:
"Two EFI fixes:

- Prevent a race and buffer overflow in the sysfs efivars interface
which causes kernel memory corruption.

- Add the missing NULL pointer checks in efivar_store_raw()"

* tag 'efi-urgent-2020-03-15' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
efi: Add a sanity check to efivar_store_raw()
efi: Fix a race and a buffer overflow while reading efivars via sysfs

+23 -9
+23 -9
drivers/firmware/efi/efivars.c
··· 83 83 efivar_attr_read(struct efivar_entry *entry, char *buf) 84 84 { 85 85 struct efi_variable *var = &entry->var; 86 + unsigned long size = sizeof(var->Data); 86 87 char *str = buf; 88 + int ret; 87 89 88 90 if (!entry || !buf) 89 91 return -EINVAL; 90 92 91 - var->DataSize = 1024; 92 - if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) 93 + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); 94 + var->DataSize = size; 95 + if (ret) 93 96 return -EIO; 94 97 95 98 if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) ··· 119 116 efivar_size_read(struct efivar_entry *entry, char *buf) 120 117 { 121 118 struct efi_variable *var = &entry->var; 119 + unsigned long size = sizeof(var->Data); 122 120 char *str = buf; 121 + int ret; 123 122 124 123 if (!entry || !buf) 125 124 return -EINVAL; 126 125 127 - var->DataSize = 1024; 128 - if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) 126 + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); 127 + var->DataSize = size; 128 + if (ret) 129 129 return -EIO; 130 130 131 131 str += sprintf(str, "0x%lx\n", var->DataSize); ··· 139 133 efivar_data_read(struct efivar_entry *entry, char *buf) 140 134 { 141 135 struct efi_variable *var = &entry->var; 136 + unsigned long size = sizeof(var->Data); 137 + int ret; 142 138 143 139 if (!entry || !buf) 144 140 return -EINVAL; 145 141 146 - var->DataSize = 1024; 147 - if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) 142 + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); 143 + var->DataSize = size; 144 + if (ret) 148 145 return -EIO; 149 146 150 147 memcpy(buf, var->Data, var->DataSize); ··· 208 199 u8 *data; 209 200 int err; 210 201 202 + if (!entry || !buf) 203 + return -EINVAL; 204 + 211 205 if (in_compat_syscall()) { 212 206 struct compat_efi_variable *compat; 213 207 ··· 262 250 { 263 251 struct efi_variable *var = &entry->var; 264 252 struct compat_efi_variable *compat; 253 + unsigned long datasize = sizeof(var->Data); 265 254 size_t size; 255 + int ret; 266 256 267 257 if (!entry || !buf) 268 258 return 0; 269 259 270 - var->DataSize = 1024; 271 - if (efivar_entry_get(entry, &entry->var.Attributes, 272 - &entry->var.DataSize, entry->var.Data)) 260 + ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data); 261 + var->DataSize = datasize; 262 + if (ret) 273 263 return -EIO; 274 264 275 265 if (in_compat_syscall()) {