Skip to content

Commit

Permalink
Merge tag 'efi-urgent-2020-03-15' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/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
  • Loading branch information
Linus Torvalds committed Mar 15, 2020
2 parents de28a65 + d6c066f commit b67775e
Showing 1 changed file with 23 additions and 9 deletions.
32 changes: 23 additions & 9 deletions drivers/firmware/efi/efivars.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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()) {
Expand Down

0 comments on commit b67775e

Please sign in to comment.