x86/efi: Correct EFI boot stub use of code32_start
authorMatt Fleming <matt@console-pimps.org>
Tue, 8 Apr 2014 12:14:00 +0000 (13:14 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 6 May 2014 14:55:30 +0000 (07:55 -0700)
commit 7e8213c1f3acc064aef37813a39f13cbfe7c3ce7 upstream.

code32_start should point at the start of the protected mode code, and
*not* at the beginning of the bzImage. This is much easier to do in
assembly so document that callers of make_boot_params() need to fill out
code32_start.

The fallout from this bug is that we would end up relocating the image
but copying the image at some offset, resulting in what appeared to be
memory corruption.

Reported-by: Thomas Bächler <thomas@archlinux.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/boot/compressed/eboot.c
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S

index d606463aa6d63bfdab5641e6bd7e6b68545e32d9..1308beed7abe861a1b8fea621b5d917e31b30cd6 100644 (file)
@@ -865,6 +865,9 @@ fail:
  * Because the x86 boot code expects to be passed a boot_params we
  * need to create one ourselves (usually the bootloader would create
  * one for us).
+ *
+ * The caller is responsible for filling out ->code32_start in the
+ * returned boot_params.
  */
 struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
 {
@@ -921,8 +924,6 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
        hdr->vid_mode = 0xffff;
        hdr->boot_flag = 0xAA55;
 
-       hdr->code32_start = (__u64)(unsigned long)image->image_base;
-
        hdr->type_of_loader = 0x21;
 
        /* Convert unicode cmdline to ascii */
index 1e3184f6072f913250b3b18371978a4fd1b3f63d..abb988a54c69337d54b62f0317d617f7dc3d108b 100644 (file)
@@ -50,6 +50,13 @@ ENTRY(efi_pe_entry)
        pushl   %eax
        pushl   %esi
        pushl   %ecx
+
+       call    reloc
+reloc:
+       popl    %ecx
+       subl    reloc, %ecx
+       movl    %ecx, BP_code32_start(%eax)
+
        sub     $0x4, %esp
 
 ENTRY(efi_stub_entry)
@@ -63,12 +70,7 @@ ENTRY(efi_stub_entry)
        hlt
        jmp     1b
 2:
-       call    3f
-3:
-       popl    %eax
-       subl    $3b, %eax
-       subl    BP_pref_address(%esi), %eax
-       add     BP_code32_start(%esi), %eax
+       movl    BP_code32_start(%esi), %eax
        leal    preferred_addr(%eax), %eax
        jmp     *%eax
 
index 16f24e6dad79826e8714a01fb5db750c1551dc6f..92059b8f3f7b74d742b7ec826d3920c55543823a 100644 (file)
@@ -217,6 +217,8 @@ ENTRY(efi_pe_entry)
        cmpq    $0,%rax
        je      1f
        mov     %rax, %rdx
+       leaq    startup_32(%rip), %rax
+       movl    %eax, BP_code32_start(%rdx)
        popq    %rsi
        popq    %rdi
 
@@ -230,12 +232,7 @@ ENTRY(efi_stub_entry)
        hlt
        jmp     1b
 2:
-       call    3f
-3:
-       popq    %rax
-       subq    $3b, %rax
-       subq    BP_pref_address(%rsi), %rax
-       add     BP_code32_start(%esi), %eax
+       movl    BP_code32_start(%esi), %eax
        leaq    preferred_addr(%rax), %rax
        jmp     *%rax