]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[romprefix] Avoid using PMM-allocated memory in UNDI loader entry point
authorMichael Brown <mcb30@ipxe.org>
Mon, 5 Dec 2016 14:11:00 +0000 (14:11 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 5 Dec 2016 15:21:45 +0000 (15:21 +0000)
The UNDI loader entry point is very likely to be called after POST,
when there is a high chance that the PMM-allocated image source area
and decompression area have been reused by something else.

In particular, using an iPXE .iso to test a separate iPXE ROM's UNDI
loader entry point in a qemu VM is likely to crash.  SeaBIOS allocates
PMM blocks from close to the top of memory and so these blocks have a
high chance of colliding with the runtime addresses subsequently
chosen by the non-ROM iPXE by scanning the INT 15,e820 memory map.

The standard romprefix.S has no choice about relying on the
PMM-allocated image source area, since it has no other way to retrieve
its compressed payload.

In mromprefix.S, the image source area functions only as an optional
buffer used to avoid repeated reads from the (potentially slow)
expansion ROM BAR by the decompression code.  We can therefore always
set %esi=0 when calling install_prealloc from the UNDI loader entry
point, and simply fall back to reading directly from the expansion ROM
BAR.

We can always set %edi=0 when calling install_prealloc from the UNDI
loader entry point.  This will behave as though the decompression area
PMM allocation failed, and will therefore use INT 15,88 to find a
temporary decompression area somewhere close to 64MB.  This is by no
means guaranteed to be safe from collisions, but it's probably safer
on balance than the PMM-allocated address.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/x86/prefix/mromprefix.S
src/arch/x86/prefix/undiloader.S

index b636b92af56464d0282cbcc5c6adfc84a5c1c432..568d1c00642f2d4c7507a30e744094364119a771 100644 (file)
@@ -456,6 +456,24 @@ pci_set_mem_access:
        ret
        .size   pci_set_mem_access, . - pci_set_mem_access
 
+/* Update image source address for UNDI loader
+ *
+ * Parameters:
+ *   %esi : Image source address
+ * Returns:
+ *   %esi : Image source address
+ */
+       .section ".prefix", "ax", @progbits
+       .globl  undiloader_source
+undiloader_source:
+       /* Always use expansion ROM BAR directly when installing via
+        * the UNDI loader entry point, since the PMM-allocated block
+        * may collide with whatever is calling the UNDI loader entry
+        * point.
+        */
+       xorl    %esi, %esi
+       ret
+
 /* Payload prefix
  *
  * We include a dummy ROM header to cover the "hidden" portion of the
index 530b48e8a3dff1b4df575607fe3b2f58f813324a..1d77110e7cc3a62bb99217395458b1f0cf74165a 100644 (file)
@@ -35,7 +35,8 @@ undiloader:
        movw    %es:12(%di), %bx
        movw    %es:14(%di), %ax
        movl    image_source, %esi
-       movl    decompress_to, %edi
+       call    undiloader_source
+       xorl    %edi, %edi
        orl     $0xffffffff, %ebp       /* Allow arbitrary relocation */
        call    install_prealloc
        popw    %di
@@ -57,3 +58,16 @@ undiloader:
        popl    %edi
        popl    %esi
        lret
+
+/* Update image source address for UNDI loader
+ *
+ * Parameters:
+ *   %esi : Image source address
+ * Returns:
+ *   %esi : Image source address
+ */
+       .section ".prefix", "ax", @progbits
+       .globl  undiloader_source
+       .weak   undiloader_source
+undiloader_source:
+       ret