mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
efi_loader: segfault in efi_clear_os_indications()
If we call efi_clear_os_indications() before initializing the memory store
for UEFI variables a NULL pointer dereference occurs.
The error was observed on the sandbox with:
usb start
host bind 0 sandbox.img
load host 0:1 $kernel_addr_r helloworld.efi
bootefi $kernel_addr_r
Here efi_resister_disk() failed due to an error in the BTRFS implementation.
Move the logic to clear EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
to the rest of the capsule code.
If CONFIG_EFI_IGNORE_OSINDICATIONS=y, we should still clear the flag.
If OsIndications does not exist, we should not create it as it is owned by
the operating system.
Fixes: 149108a3eb
("efi_loader: clear OsIndications")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
parent
1ae35c72b8
commit
9d1564dabc
2 changed files with 30 additions and 49 deletions
|
@ -1037,30 +1037,45 @@ efi_status_t __weak efi_load_capsule_drivers(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* check_run_capsules - Check whether capsule update should run
|
||||
* check_run_capsules() - check whether capsule update should run
|
||||
*
|
||||
* The spec says OsIndications must be set in order to run the capsule update
|
||||
* on-disk. Since U-Boot doesn't support runtime SetVariable, allow capsules to
|
||||
* run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected
|
||||
*
|
||||
* Return: EFI_SUCCESS if update to run, EFI_NOT_FOUND otherwise
|
||||
*/
|
||||
static bool check_run_capsules(void)
|
||||
static efi_status_t check_run_capsules(void)
|
||||
{
|
||||
u64 os_indications;
|
||||
efi_uintn_t size;
|
||||
efi_status_t ret;
|
||||
|
||||
if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS))
|
||||
return true;
|
||||
efi_status_t r;
|
||||
|
||||
size = sizeof(os_indications);
|
||||
ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
|
||||
NULL, &size, &os_indications, NULL);
|
||||
if (ret == EFI_SUCCESS &&
|
||||
(os_indications
|
||||
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED))
|
||||
return true;
|
||||
r = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
|
||||
NULL, &size, &os_indications, NULL);
|
||||
if (r != EFI_SUCCESS || size != sizeof(os_indications))
|
||||
return EFI_NOT_FOUND;
|
||||
|
||||
return false;
|
||||
if (os_indications &
|
||||
EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) {
|
||||
os_indications &=
|
||||
~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
|
||||
r = efi_set_variable_int(L"OsIndications",
|
||||
&efi_global_variable_guid,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(os_indications),
|
||||
&os_indications, false);
|
||||
if (r != EFI_SUCCESS)
|
||||
log_err("Setting %ls failed\n", L"OsIndications");
|
||||
return EFI_SUCCESS;
|
||||
} else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1078,7 +1093,7 @@ efi_status_t efi_launch_capsules(void)
|
|||
unsigned int nfiles, index, i;
|
||||
efi_status_t ret;
|
||||
|
||||
if (!check_run_capsules())
|
||||
if (check_run_capsules() != EFI_SUCCESS)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
index = get_last_capsule();
|
||||
|
|
|
@ -175,36 +175,6 @@ static efi_status_t efi_init_os_indications(void)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* efi_clear_os_indications() - clear OsIndications
|
||||
*
|
||||
* Clear EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
|
||||
*/
|
||||
static efi_status_t efi_clear_os_indications(void)
|
||||
{
|
||||
efi_uintn_t size;
|
||||
u64 os_indications;
|
||||
efi_status_t ret;
|
||||
|
||||
size = sizeof(os_indications);
|
||||
ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
|
||||
NULL, &size, &os_indications, NULL);
|
||||
if (ret != EFI_SUCCESS)
|
||||
os_indications = 0;
|
||||
else
|
||||
os_indications &=
|
||||
~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
|
||||
ret = efi_set_variable_int(L"OsIndications", &efi_global_variable_guid,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(os_indications), &os_indications,
|
||||
false);
|
||||
if (ret != EFI_SUCCESS)
|
||||
log_err("Setting %ls failed\n", L"OsIndications");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_init_obj_list() - Initialize and populate EFI object list
|
||||
*
|
||||
|
@ -212,7 +182,7 @@ static efi_status_t efi_clear_os_indications(void)
|
|||
*/
|
||||
efi_status_t efi_init_obj_list(void)
|
||||
{
|
||||
efi_status_t r, ret = EFI_SUCCESS;
|
||||
efi_status_t ret = EFI_SUCCESS;
|
||||
|
||||
/* Initialize once only */
|
||||
if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
|
||||
|
@ -331,11 +301,7 @@ efi_status_t efi_init_obj_list(void)
|
|||
if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) &&
|
||||
!IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
|
||||
ret = efi_launch_capsules();
|
||||
|
||||
out:
|
||||
r = efi_clear_os_indications();
|
||||
if (ret == EFI_SUCCESS)
|
||||
ret = r;
|
||||
efi_obj_list_initialized = ret;
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue