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
This commit is contained in:
@@ -83,13 +83,16 @@ static ssize_t
|
||||
efivar_attr_read(struct efivar_entry *entry, char *buf)
|
||||
{
|
||||
struct efi_variable *var = &entry->var;
|
||||
unsigned long size = sizeof(var->Data);
|
||||
char *str = buf;
|
||||
int ret;
|
||||
|
||||
if (!entry || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
var->DataSize = 1024;
|
||||
if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
|
||||
ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
|
||||
var->DataSize = size;
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
|
||||
@@ -116,13 +119,16 @@ static ssize_t
|
||||
efivar_size_read(struct efivar_entry *entry, char *buf)
|
||||
{
|
||||
struct efi_variable *var = &entry->var;
|
||||
unsigned long size = sizeof(var->Data);
|
||||
char *str = buf;
|
||||
int ret;
|
||||
|
||||
if (!entry || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
var->DataSize = 1024;
|
||||
if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
|
||||
ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
|
||||
var->DataSize = size;
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
str += sprintf(str, "0x%lx\n", var->DataSize);
|
||||
@@ -133,12 +139,15 @@ static ssize_t
|
||||
efivar_data_read(struct efivar_entry *entry, char *buf)
|
||||
{
|
||||
struct efi_variable *var = &entry->var;
|
||||
unsigned long size = sizeof(var->Data);
|
||||
int ret;
|
||||
|
||||
if (!entry || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
var->DataSize = 1024;
|
||||
if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
|
||||
ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
|
||||
var->DataSize = size;
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
memcpy(buf, var->Data, var->DataSize);
|
||||
@@ -199,6 +208,9 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
|
||||
u8 *data;
|
||||
int err;
|
||||
|
||||
if (!entry || !buf)
|
||||
return -EINVAL;
|
||||
|
||||
if (in_compat_syscall()) {
|
||||
struct compat_efi_variable *compat;
|
||||
|
||||
@@ -250,14 +262,16 @@ efivar_show_raw(struct efivar_entry *entry, char *buf)
|
||||
{
|
||||
struct efi_variable *var = &entry->var;
|
||||
struct compat_efi_variable *compat;
|
||||
unsigned long datasize = sizeof(var->Data);
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
if (!entry || !buf)
|
||||
return 0;
|
||||
|
||||
var->DataSize = 1024;
|
||||
if (efivar_entry_get(entry, &entry->var.Attributes,
|
||||
&entry->var.DataSize, entry->var.Data))
|
||||
ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data);
|
||||
var->DataSize = datasize;
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
if (in_compat_syscall()) {
|
||||
|
Reference in New Issue
Block a user