From f5bbe7ec4a4b31ad197947b025c54a8e87402436 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 18 Jan 2012 00:02:16 +0000 Subject: [PATCH] [lkrnprefix] Copy command line before installing iPXE The command line may be situated in an area of base memory that will be overwritten by iPXE's real-mode segments, causing the command line to be corrupted before it can be used. Fix by creating a copy of the command line on the prefix stack (below 0x7c00) before installing the real-mode segments. Reported-by: Dave Hansen Signed-off-by: Michael Brown --- src/arch/i386/core/runtime.c | 3 ++- src/arch/i386/prefix/lkrnprefix.S | 43 ++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/arch/i386/core/runtime.c b/src/arch/i386/core/runtime.c index 09ba62568..2ad8c20a4 100644 --- a/src/arch/i386/core/runtime.c +++ b/src/arch/i386/core/runtime.c @@ -132,7 +132,8 @@ static int cmdline_init ( void ) { } cmdline = cmdline_copy; copy_from_user ( cmdline, cmdline_user, 0, len ); - DBGC ( colour, "RUNTIME found command line \"%s\"\n", cmdline ); + DBGC ( colour, "RUNTIME found command line \"%s\" at %08x\n", + cmdline, cmdline_phys ); /* Strip unwanted cruft from the command line */ cmdline_strip ( cmdline, "BOOT_IMAGE=" ); diff --git a/src/arch/i386/prefix/lkrnprefix.S b/src/arch/i386/prefix/lkrnprefix.S index bc1f8bfb7..768903326 100644 --- a/src/arch/i386/prefix/lkrnprefix.S +++ b/src/arch/i386/prefix/lkrnprefix.S @@ -188,17 +188,52 @@ setup_code: We're now at the beginning of the kernel proper. */ run_ipxe: - /* Set up stack just below 0x7c00 */ + /* Set up stack just below 0x7c00 and clear direction flag */ xorw %ax, %ax movw %ax, %ss movw $0x7c00, %sp + cld /* Retrieve command-line pointer */ - movl %es:cmd_line_ptr, %edx + movl %ds:cmd_line_ptr, %edx + testl %edx, %edx + jz no_cmd_line + + /* Set up %es:%di to point to command line */ + movl %edx, %edi + andl $0xf, %edi + rorl $4, %edx + movw %dx, %es + + /* Find length of command line */ + pushw %di + movw $0xffff, %cx + repnz scasb + notw %cx + popw %si + + /* Make space for command line on stack */ + movw %sp, %di + subw %cx, %di + andw $~0xf, %di + movw %di, %sp + + /* Copy command line to stack */ + pushw %ds + pushw %es + popw %ds + pushw %ss + popw %es + rep movsb + popw %ds + + /* Store new command-line pointer */ + movzwl %sp, %edx +no_cmd_line: /* Retrieve initrd pointer and size */ - movl %es:ramdisk_image, %ebp - movl %es:ramdisk_size, %ecx + movl %ds:ramdisk_image, %ebp + movl %ds:ramdisk_size, %ecx /* Install iPXE */ call alloc_basemem