lkml.org 
[lkml]   [2007]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 16/19] x86 setup: handle boot loaders which set up the stack incorrectly
    -stable review patch.  If anyone has any objections, please let us know.

    ------------------
    From: H. Peter Anvin <hpa@zytor.com>

    patch 6b6815c6d5d1dc209701d1661a7a0e09a295db2f in mainline.

    Apparently some specific versions of LILO enter the kernel with a
    stack pointer that doesn't match the rest of the segments. Make our
    best attempt at untangling the resulting mess.

    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    arch/i386/boot/boot.h | 4 +--
    arch/i386/boot/header.S | 62 ++++++++++++++++++++++++++++++++++--------------
    2 files changed, 46 insertions(+), 20 deletions(-)

    --- a/arch/i386/boot/boot.h
    +++ b/arch/i386/boot/boot.h
    @@ -17,6 +17,8 @@
    #ifndef BOOT_BOOT_H
    #define BOOT_BOOT_H

    +#define STACK_SIZE 512 /* Minimum number of bytes for stack */
    +
    #ifndef __ASSEMBLY__

    #include <stdarg.h>
    @@ -198,8 +200,6 @@ static inline int isdigit(int ch)
    }

    /* Heap -- available for dynamic lists. */
    -#define STACK_SIZE 512 /* Minimum number of bytes for stack */
    -
    extern char _end[];
    extern char *HEAP;
    extern char *heap_end;
    --- a/arch/i386/boot/header.S
    +++ b/arch/i386/boot/header.S
    @@ -173,7 +173,8 @@ ramdisk_size: .long 0 # its size in byt
    bootsect_kludge:
    .long 0 # obsolete

    -heap_end_ptr: .word _end+1024 # (Header version 0x0201 or later)
    +heap_end_ptr: .word _end+STACK_SIZE-512
    + # (Header version 0x0201 or later)
    # space from here (exclusive) down to
    # end of setup code can be used by setup
    # for local heap purposes.
    @@ -225,28 +226,53 @@ start_of_setup:
    int $0x13
    #endif

    -# We will have entered with %cs = %ds+0x20, normalize %cs so
    -# it is on par with the other segments.
    - pushw %ds
    - pushw $setup2
    - lretw
    -
    -setup2:
    # Force %es = %ds
    movw %ds, %ax
    movw %ax, %es
    cld

    -# Stack paranoia: align the stack and make sure it is good
    -# for both 16- and 32-bit references. In particular, if we
    -# were meant to have been using the full 16-bit segment, the
    -# caller might have set %sp to zero, which breaks %esp-based
    -# references.
    - andw $~3, %sp # dword align (might as well...)
    - jnz 1f
    - movw $0xfffc, %sp # Make sure we're not zero
    -1: movzwl %sp, %esp # Clear upper half of %esp
    - sti
    +# Apparently some ancient versions of LILO invoked the kernel
    +# with %ss != %ds, which happened to work by accident for the
    +# old code. If the CAN_USE_HEAP flag is set in loadflags, or
    +# %ss != %ds, then adjust the stack pointer.
    +
    + # Smallest possible stack we can tolerate
    + movw $(_end+STACK_SIZE), %cx
    +
    + movw heap_end_ptr, %dx
    + addw $512, %dx
    + jnc 1f
    + xorw %dx, %dx # Wraparound - whole segment available
    +1: testb $CAN_USE_HEAP, loadflags
    + jnz 2f
    +
    + # No CAN_USE_HEAP
    + movw %ss, %dx
    + cmpw %ax, %dx # %ds == %ss?
    + movw %sp, %dx
    + # If so, assume %sp is reasonably set, otherwise use
    + # the smallest possible stack.
    + jne 4f # -> Smallest possible stack...
    +
    + # Make sure the stack is at least minimum size. Take a value
    + # of zero to mean "full segment."
    +2:
    + andw $~3, %dx # dword align (might as well...)
    + jnz 3f
    + movw $0xfffc, %dx # Make sure we're not zero
    +3: cmpw %cx, %dx
    + jnb 5f
    +4: movw %cx, %dx # Minimum value we can possibly use
    +5: movw %ax, %ss
    + movzwl %dx, %esp # Clear upper half of %esp
    + sti # Now we should have a working stack
    +
    +# We will have entered with %cs = %ds+0x20, normalize %cs so
    +# it is on par with the other segments.
    + pushw %ds
    + pushw $6f
    + lretw
    +6:

    # Check signature at end of setup
    cmpl $0x5a5aaa55, setup_sig
    --
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-11-15 07:25    [W:0.026 / U:149.032 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site