lkml.org 
[lkml]   [2003]   [Oct]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [x86] Access off the bottom of stack causes a segfault?
    On Tue, 14 Oct 2003, Chris Lattner wrote:

    >
    > My compiler is generating accesses off the bottom of the stack (address
    > below %esp). Is there some funny kernel interaction that I should be
    > aware of with this? I'm periodically getting segfaults.
    >
    > Example:
    >
    > int main() {
    > int test[4000];
    > ...
    > return 0;
    > }
    >
    > Generated code:
    > .intel_syntax
    > ...
    > main:
    > mov DWORD PTR [%ESP - 16004], %EBP # Save EBP to stack

    BAM **INTERRUPT** writes return address below stack-pointer.

    > mov %EBP, %ESP # Set up EBP
    > sub %ESP, 16004 # Finally adjust ESP
    > lea %EAX, DWORD PTR [%EBP - 16000] # Get the address of the array
    > ...
    > mov %EAX, 0 # Setup return value
    > mov %ESP, %EBP # restore ESP
    > mov %EBP, DWORD PTR [%ESP - 16004] # Restore EBP from stack

    BAM **You get bad data, overwritten by interrupt**

    > ret
    >
    > This seems like perfectly valid X86 code (though unconventional), but it
    > is causing segfaults pretty consistently (on the first instruction).
    > Does the linux kernel assume that page faults will be above the stack
    > pointer if the stack needs to be expanded?
    >
    > Thanks,
    >
    > -Chris

    Well it is perfectly bad code. You can't access data elements
    below the stack-pointer because that's where the return address
    form interrupts, etc., will go. If you write there, you overwrite
    that information, in particular an interrupt overwrites what
    you put there. You do 'own' that address space, but you
    can't use it in a program.

    This script shows how to allocate stack-data without running
    into that problem.


    #!/bin/bash
    #
    # Using only assembly and not any 'C' stuff, this allocates
    # 64k on the stack and writes to it.
    #
    FNAME=/tmp/tmp
    cat <<EOF >${FNAME}.S
    .section .text
    .global _start
    .type _start,@function
    _start: pushl %ebp # Save
    movl %esp, %ebp # Save SP
    subl \$0x10000,%esp # 64 k on the stack
    movl \$0, (%esp) # Write there
    movl %ebp, %esp # Original SP
    popl %ebp # Restore
    movl \$0x01, %eax # Exit function
    movl \$0x00, %ebx # Exit code
    int \$0x80
    1: jmp 1b # Hard stop
    .end
    EOF
    as -o ${FNAME}.o ${FNAME}.S
    ld -o ${FNAME} ${FNAME}.o
    rm -f core
    ${FNAME}
    if [ -f "core" ] ; then echo "Something's bad!" ; else echo "Okay!" ; fi
    #

    Cheers,
    Dick Johnson
    Penguin : Linux version 2.4.22 on an i686 machine (797.90 BogoMips).
    Note 96.31% of all statistics are fiction.
    -
    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: 2005-03-22 13:49    [W:0.024 / U:121.596 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site