diff options
author | Vladis Dronov <vdronov@redhat.com> | 2020-03-08 09:08:54 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2020-03-08 09:56:34 +0100 |
commit | 286d3250c9d6437340203fb64938bea344729a0e (patch) | |
tree | 28eee8f847ed45308de8bea0a26c772d55d384c4 /arch/x86/kernel | |
parent | 61a09258f2e5b48ad0605131cae9a33ce4d01a9d (diff) | |
download | linux-286d3250c9d6437340203fb64938bea344729a0e.tar.gz linux-286d3250c9d6437340203fb64938bea344729a0e.tar.bz2 linux-286d3250c9d6437340203fb64938bea344729a0e.zip |
efi: Fix a race and a buffer overflow while reading efivars via sysfs
There is a race and a buffer overflow corrupting a kernel memory while
reading an EFI variable with a size more than 1024 bytes via the older
sysfs method. This happens because accessing struct efi_variable in
efivar_{attr,size,data}_read() and friends is not protected from
a concurrent access leading to a kernel memory corruption and, at best,
to a crash. The race scenario is the following:
CPU0: CPU1:
efivar_attr_read()
var->DataSize = 1024;
efivar_entry_get(... &var->DataSize)
down_interruptible(&efivars_lock)
efivar_attr_read() // same EFI var
var->DataSize = 1024;
efivar_entry_get(... &var->DataSize)
down_interruptible(&efivars_lock)
virt_efi_get_variable()
// returns EFI_BUFFER_TOO_SMALL but
// var->DataSize is set to a real
// var size more than 1024 bytes
up(&efivars_lock)
virt_efi_get_variable()
// called with var->DataSize set
// to a real var size, returns
// successfully and overwrites
// a 1024-bytes kernel buffer
up(&efivars_lock)
This can be reproduced by concurrent reading of an EFI variable which size
is more than 1024 bytes:
ts# for cpu in $(seq 0 $(nproc --ignore=1)); do ( taskset -c $cpu \
cat /sys/firmware/efi/vars/KEKDefault*/size & ) ; done
Fix this by using a local variable for a var's data buffer size so it
does not get overwritten.
Fixes: e14ab23dde12b80d ("efivars: efivar_entry API")
Reported-by: Bob Sanders <bob.sanders@hpe.com> and the LTP testsuite
Signed-off-by: Vladis Dronov <vdronov@redhat.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20200305084041.24053-2-vdronov@redhat.com
Link: https://lore.kernel.org/r/20200308080859.21568-24-ardb@kernel.org
Diffstat (limited to 'arch/x86/kernel')
0 files changed, 0 insertions, 0 deletions