[PATCH] [efi] Raise TPL during driver entry point

As per commit c89a446 ("[efi] Run at TPL_CALLBACK to protect against
UEFI timers") we expect to run at TPL_CALLBACK almost all of the time.
Various code paths rely on this assumption.  Code paths that need to
temporarily lower the TPL (e.g. for entropy gathering) will restore it
to TPL_CALLBACK.

The entropy gathering code will be run during DRBG initialisation,
which happens during the call to startup().  In the case of iPXE
compiled as an EFI application this code will run within the scope of
efi_snp_claim() and so will execute at TPL_CALLBACK as expected.

In the case of iPXE compiled as an EFI driver the code will
incorrectly run at TPL_APPLICATION since there is nothing within the
EFI driver entry point that raises (and restores) the TPL.  The net
effect is that a build that includes the entropy-gathering code
(e.g. a build with HTTPS enabled) will return from the driver entry
point at TPL_CALLBACK, which causes a system lockup.

Fix by raising and restoring the TPL within the EFI driver entry
point.

Debugged-by: Ignat Korchagin <ignat@cloudflare.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>

Origin: backport, 2ae5d43386
Bug-Ubuntu: https://bugs.launchpad.net/bugs/1882671
Last-Update: 2020-07-16


Gbp-Pq: Name lp-1882671-efi-Raise-TPL-during-driver-entry-point.patch
This commit is contained in:
Michael Brown 2020-06-30 16:32:59 +01:00 committed by Cong Liu
parent ec7ca7fdea
commit f7b78ba1e5
1 changed files with 9 additions and 0 deletions

View File

@ -34,16 +34,25 @@ FILE_LICENCE ( GPL2_OR_LATER );
*/ */
EFI_STATUS EFIAPI _efidrv_start ( EFI_HANDLE image_handle, EFI_STATUS EFIAPI _efidrv_start ( EFI_HANDLE image_handle,
EFI_SYSTEM_TABLE *systab ) { EFI_SYSTEM_TABLE *systab ) {
EFI_BOOT_SERVICES *bs;
EFI_TPL saved_tpl;
EFI_STATUS efirc; EFI_STATUS efirc;
/* Initialise EFI environment */ /* Initialise EFI environment */
if ( ( efirc = efi_init ( image_handle, systab ) ) != 0 ) if ( ( efirc = efi_init ( image_handle, systab ) ) != 0 )
return efirc; return efirc;
/* Raise TPL */
bs = efi_systab->BootServices;
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
/* Initialise iPXE environment */ /* Initialise iPXE environment */
initialise(); initialise();
startup(); startup();
/* Restore TPL */
bs->RestoreTPL ( saved_tpl );
return 0; return 0;
} }