Skip to content

Commit

Permalink
[wim] Always process .wim image file last
Browse files Browse the repository at this point in the history
The order of input files is undefined on a UEFI system, which could
potentially lead to a situation in which a file automatically
extracted from a .wim image takes priority over a file provided
explicitly.

This issue has not arisen in practice since wimboot is almost always
loaded by iPXE, and iPXE happens to preserve the order of downloaded
files within the virtual filesystem.

Fix by deferring processing of the .wim file until after all other
input files have been read.

Modify the automated test script to place the .wim download in between
two files that are both required for the test to pass.

Signed-off-by: Michael Brown <mbrown@fensystems.co.uk>
  • Loading branch information
mcb30 committed Feb 11, 2021
1 parent 699f810 commit 1f974a4
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 17 deletions.
22 changes: 14 additions & 8 deletions src/efifile.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ void efi_extract ( EFI_HANDLE handle ) {
CHAR16 name[ VDISK_NAME_LEN + 1 /* WNUL */ ];
} __attribute__ (( packed )) info;
char name[ VDISK_NAME_LEN + 1 /* NUL */ ];
struct vdisk_file *wim = NULL;
struct vdisk_file *vfile;
EFI_FILE_PROTOCOL *root;
EFI_FILE_PROTOCOL *file;
Expand Down Expand Up @@ -212,17 +213,22 @@ void efi_extract ( EFI_HANDLE handle ) {
} else if ( wcscasecmp ( ( wname + ( wcslen ( wname ) - 4 ) ),
L".wim" ) == 0 ) {
DBG ( "...found WIM file %ls\n", wname );
vdisk_patch_file ( vfile, patch_wim );
if ( ( ! bootmgfw ) &&
( bootmgfw = wim_add_file ( vfile, cmdline_index,
bootmgfw_path,
efi_bootarch() ) ) ) {
DBG ( "...extracted %ls\n", bootmgfw_path );
}
wim_add_files ( vfile, cmdline_index, efi_wim_paths );
wim = vfile;
}
}

/* Process WIM image */
if ( wim ) {
vdisk_patch_file ( wim, patch_wim );
if ( ( ! bootmgfw ) &&
( bootmgfw = wim_add_file ( wim, cmdline_index,
bootmgfw_path,
efi_bootarch() ) ) ) {
DBG ( "...extracted %ls\n", bootmgfw_path );
}
wim_add_files ( wim, cmdline_index, efi_wim_paths );
}

/* Check that we have a boot file */
if ( ! bootmgfw ) {
die ( "FATAL: no %ls or bootmgfw.efi found\n",
Expand Down
24 changes: 16 additions & 8 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ static const wchar_t *wim_paths[] = {
/** bootmgr.exe file */
static struct vdisk_file *bootmgr;

/** WIM image file */
static struct vdisk_file *bootwim;

/** Minimal length of embedded bootmgr.exe */
#define BOOTMGR_MIN_LEN 16384

Expand Down Expand Up @@ -364,14 +367,7 @@ static int add_file ( const char *name, void *data, size_t len ) {
} else if ( strcasecmp ( ( name + strlen ( name ) - 4 ),
".wim" ) == 0 ) {
DBG ( "...found WIM file %s\n", name );
vdisk_patch_file ( file, patch_wim );
if ( ( ! bootmgr ) &&
( bootmgr = wim_add_file ( file, cmdline_index,
bootmgr_path,
L"bootmgr.exe" ) ) ) {
DBG ( "...extracted bootmgr.exe\n" );
}
wim_add_files ( file, cmdline_index, wim_paths );
bootwim = file;
}

return 0;
Expand Down Expand Up @@ -447,6 +443,18 @@ int main ( void ) {
if ( cpio_extract ( initrd, initrd_len, add_file ) != 0 )
die ( "FATAL: could not extract initrd files\n" );

/* Process WIM image */
if ( bootwim ) {
vdisk_patch_file ( bootwim, patch_wim );
if ( ( ! bootmgr ) &&
( bootmgr = wim_add_file ( bootwim, cmdline_index,
bootmgr_path,
L"bootmgr.exe" ) ) ) {
DBG ( "...extracted bootmgr.exe\n" );
}
wim_add_files ( bootwim, cmdline_index, wim_paths );
}

/* Add INT 13 drive */
callback.drive = initialise_int13();

Expand Down
2 changes: 1 addition & 1 deletion test/testwimboot
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def ipxe_script(uuid, version, arch, bootmgr, bcd, bootsdi, bootargs):
#!ipxe
kernel ../wimboot {bootargs}
initrd -n qr.txt qr-{uuid}.txt qr.txt
initrd ../images/{version}/{arch}/sources/boot.wim boot.wim
initrd ../winpeshl.ini winpeshl.ini
""").lstrip()
if bootmgr:
Expand All @@ -74,7 +75,6 @@ def ipxe_script(uuid, version, arch, bootmgr, bcd, bootsdi, bootargs):
initrd ../images/{version}/{arch}/boot/boot.sdi boot.sdi
""").lstrip()
script += textwrap.dedent(f"""
initrd ../images/{version}/{arch}/sources/boot.wim boot.wim
boot
""").lstrip()
return script
Expand Down

0 comments on commit 1f974a4

Please sign in to comment.