Messages in this thread | | | Date | Tue, 14 Oct 2003 15:18:39 -0400 (EDT) | From | "Richard B. Johnson" <> | Subject | Re: [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/
| |