Commit 065487a1 authored by Matt Fleming's avatar Matt Fleming Committed by Jiri Slaby

x86/efi: Correct EFI boot stub use of code32_start

commit 7e8213c1 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: default avatarThomas Bächler <thomas@archlinux.org>
Signed-off-by: default avatarMatt Fleming <matt.fleming@intel.com>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
parent 56999c6b
...@@ -865,6 +865,9 @@ static efi_status_t handle_ramdisks(efi_loaded_image_t *image, ...@@ -865,6 +865,9 @@ static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
* Because the x86 boot code expects to be passed a boot_params we * Because the x86 boot code expects to be passed a boot_params we
* need to create one ourselves (usually the bootloader would create * need to create one ourselves (usually the bootloader would create
* one for us). * 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) 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) ...@@ -921,8 +924,6 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
hdr->vid_mode = 0xffff; hdr->vid_mode = 0xffff;
hdr->boot_flag = 0xAA55; hdr->boot_flag = 0xAA55;
hdr->code32_start = (__u64)(unsigned long)image->image_base;
hdr->type_of_loader = 0x21; hdr->type_of_loader = 0x21;
/* Convert unicode cmdline to ascii */ /* Convert unicode cmdline to ascii */
......
...@@ -50,6 +50,13 @@ ENTRY(efi_pe_entry) ...@@ -50,6 +50,13 @@ ENTRY(efi_pe_entry)
pushl %eax pushl %eax
pushl %esi pushl %esi
pushl %ecx pushl %ecx
call reloc
reloc:
popl %ecx
subl reloc, %ecx
movl %ecx, BP_code32_start(%eax)
sub $0x4, %esp sub $0x4, %esp
ENTRY(efi_stub_entry) ENTRY(efi_stub_entry)
...@@ -63,12 +70,7 @@ ENTRY(efi_stub_entry) ...@@ -63,12 +70,7 @@ ENTRY(efi_stub_entry)
hlt hlt
jmp 1b jmp 1b
2: 2:
call 3f movl BP_code32_start(%esi), %eax
3:
popl %eax
subl $3b, %eax
subl BP_pref_address(%esi), %eax
add BP_code32_start(%esi), %eax
leal preferred_addr(%eax), %eax leal preferred_addr(%eax), %eax
jmp *%eax jmp *%eax
......
...@@ -215,6 +215,8 @@ ENTRY(efi_pe_entry) ...@@ -215,6 +215,8 @@ ENTRY(efi_pe_entry)
cmpq $0,%rax cmpq $0,%rax
je 1f je 1f
mov %rax, %rdx mov %rax, %rdx
leaq startup_32(%rip), %rax
movl %eax, BP_code32_start(%rdx)
popq %rsi popq %rsi
popq %rdi popq %rdi
...@@ -228,12 +230,7 @@ ENTRY(efi_stub_entry) ...@@ -228,12 +230,7 @@ ENTRY(efi_stub_entry)
hlt hlt
jmp 1b jmp 1b
2: 2:
call 3f movl BP_code32_start(%esi), %eax
3:
popq %rax
subq $3b, %rax
subq BP_pref_address(%rsi), %rax
add BP_code32_start(%esi), %eax
leaq preferred_addr(%rax), %rax leaq preferred_addr(%rax), %rax
jmp *%rax jmp *%rax
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment