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.

efivars: only check for duplicates on the registered list

variable_is_present() accesses '__efivars' directly, but when called via
gsmi_init() Michel reports observing the following crash,

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: variable_is_present+0x55/0x170
Call Trace:
register_efivars+0x106/0x370
gsmi_init+0x2ad/0x3da
do_one_initcall+0x3f/0x170

The reason for the crash is that '__efivars' hasn't been initialised nor
has it been registered with register_efivars() by the time the google
EFI SMI driver runs. The gsmi code uses its own struct efivars, and
therefore, a different variable list. Fix the above crash by passing
the registered struct efivars to variable_is_present(), so that we
traverse the correct list.

Reported-by: Michel Lespinasse <walken@google.com>
Tested-by: Michel Lespinasse <walken@google.com>
Cc: Mike Waychison <mikew@google.com>
Cc: Matthew Garrett <matthew.garrett@nebula.com>
Cc: Seiji Aguchi <seiji.aguchi@hds.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Matt Fleming and committed by
Linus Torvalds
f464246d 37b7f3c7

+7 -5
+7 -5
drivers/firmware/efivars.c
··· 1628 1628 return count; 1629 1629 } 1630 1630 1631 - static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor) 1631 + static bool variable_is_present(struct efivars *efivars, 1632 + efi_char16_t *variable_name, 1633 + efi_guid_t *vendor) 1632 1634 { 1633 1635 struct efivar_entry *entry, *n; 1634 - struct efivars *efivars = &__efivars; 1635 1636 unsigned long strsize1, strsize2; 1636 1637 bool found = false; 1637 1638 ··· 1704 1703 if (status != EFI_SUCCESS) { 1705 1704 break; 1706 1705 } else { 1707 - if (!variable_is_present(variable_name, 1708 - &vendor)) { 1706 + if (!variable_is_present(efivars, 1707 + variable_name, &vendor)) { 1709 1708 found = true; 1710 1709 break; 1711 1710 } ··· 2009 2008 * we'll ever see a different variable name, 2010 2009 * and may end up looping here forever. 2011 2010 */ 2012 - if (variable_is_present(variable_name, &vendor_guid)) { 2011 + if (variable_is_present(efivars, variable_name, 2012 + &vendor_guid)) { 2013 2013 dup_variable_bug(variable_name, &vendor_guid, 2014 2014 variable_name_size); 2015 2015 status = EFI_NOT_FOUND;