[efi] Defer local download process until file has been opened

When iPXE is downloading a file from an EFI_FILE_PROTOCOL instance
backed by an EFI_BLOCK_IO_PROTOCOL instance provided by the same iPXE
binary (e.g. via a hooked SAN device), then it is possible for step()
to be invoked as a result of the calls into the EFI_BLOCK_IO_PROTOCOL
methods.  This can potentially result in efi_local_step() being run
prematurely, before the file has been opened and before the parent
interface has been attached.

Fix by deferring starting the download process until immediately prior
to returning from efi_local_open().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/158/head
Michael Brown 2020-10-13 19:08:25 +01:00
parent 6d680bdec5
commit 02748d0a58
1 changed files with 5 additions and 2 deletions

View File

@ -548,8 +548,8 @@ static int efi_local_open ( struct interface *xfer, struct uri *uri ) {
}
ref_init ( &local->refcnt, NULL );
intf_init ( &local->xfer, &efi_local_xfer_desc, &local->refcnt );
process_init ( &local->process, &efi_local_process_desc,
&local->refcnt );
process_init_stopped ( &local->process, &efi_local_process_desc,
&local->refcnt );
/* Open specified volume */
if ( ( rc = efi_local_open_volume ( local, volume ) ) != 0 )
@ -563,6 +563,9 @@ static int efi_local_open ( struct interface *xfer, struct uri *uri ) {
if ( ( rc = efi_local_len ( local ) ) != 0 )
goto err_len;
/* Start download process */
process_add ( &local->process );
/* Attach to parent interface, mortalise self, and return */
intf_plug_plug ( &local->xfer, xfer );
ref_put ( &local->refcnt );