amd64/163710: setjump in userboot.so causes stack corruption
Russell Cattelan
cattelan at digitalelves.com
Fri Dec 30 03:20:11 UTC 2011
>Number: 163710
>Category: amd64
>Synopsis: setjump in userboot.so causes stack corruption
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-amd64
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Dec 30 03:20:10 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator: Russell Cattelan
>Release: FreeBSD 9.0
>Organization:
Digtal Elves Inc
>Environment:
FreeBSD fbsd9-it 9.0-PRERELEASE FreeBSD 9.0-PRERELEASE #183: Thu Dec 29 20:20:10 CST 2011 cattelan at fbsd9-it:/sys/amd64/compile/KLOAD-CAMDEBUG amd64
>Description:
For some reason the forth interpreter is built and linked as 32bit even
on amd64.
The specific problem is that the header files used when compiling 32 are
the i386 variant which define the jmp_buf as such
#define _JBLEN 11 /* Size of the jmp_buf on x86. */
typedef struct _jmp_buf { int _jb[_JBLEN + 1]; } jmp_buf[1];
which results in a struct of 48 bytes
unfortunately libstand has a specific version of setjmp that wants to store
12 - 8 byte values
ENTRY(_setjmp)
movq %rdi,%rax
movq 0(%rsp),%rdx /* retval */
movq %rdx, 0(%rax) /* 0; retval */
movq %rbx, 8(%rax) /* 1; rbx */
movq %rsp,16(%rax) /* 2; rsp */
movq %rbp,24(%rax) /* 3; rbp */
movq %r12,32(%rax) /* 4; r12 */
movq %r13,40(%rax) /* 5; r13 */
movq %r14,48(%rax) /* 6; r14 */
movq %r15,56(%rax) /* 7; r15 */
fnstcw 64(%rax) /* 8; fpu cw */
stmxcsr 68(%rax) /* and mxcsr */
xorq %rax,%rax
ret
END(_setjmp)
What is happening then in the function ficlExecC
the saveTib was getting corrupted due to the jmpbuf stack variable
getting over written.
This causes bogus values to be places in the saveTib structure
which eventually results in a fault.
This fix is to compile the forth interpreter as 64 bit when running on amd64
>How-To-Repeat:
>Fix:
commit ad5840c9e38ba05bdcab3c9efea1c73272bbd9b7
Author: Russell Cattelan <cattelan at digitalelves.com>
Date: Thu Dec 29 20:50:57 2011 -0600
Change the build of forth interpreter to 64bit.
The main problem is that the jmp_buf structure is
half the size it needs to be 12 * 4 vs 12 * 8
The setjump functions was then causing stack corruption
since the buffer was not large enough.
diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile
index 5cf54c8..75f4349 100644
--- a/sys/boot/ficl/Makefile
+++ b/sys/boot/ficl/Makefile
@@ -8,7 +8,6 @@ SRCS= ${BASE_SRCS} sysdep.c softcore.c
CLEANFILES= softcore.c testmain testmain.o
CFLAGS+= -ffreestanding -g3
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
-CFLAGS+= -mpreferred-stack-boundary=2
CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
.endif
.if ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_CPUARCH} == "arm"
@@ -38,10 +37,6 @@ SOFTWORDS= softcore.fr jhlocal.fr marker.fr freebsd.fr ficllocal.fr \
# Optional OO extension softwords
#SOFTWORDS+= oo.fr classes.fr
-.if ${MACHINE_CPUARCH} == "amd64"
-CFLAGS+= -m32 -march=i386 -I.
-.endif
-
.if ${MACHINE_ARCH} == "powerpc64"
CFLAGS+= -m32 -mcpu=powerpc -I.
.endif
@@ -59,7 +54,8 @@ ${SRCS:M*.c:R:S/$/.o/g}: machine
beforedepend ${OBJS}: machine
machine:
- ln -sf ${.CURDIR}/../../i386/include machine
+ rm -f machine
+ ln -sf ${.CURDIR}/../../${MACHINE_CPUARCH}/include machine
CLEANFILES+= machine
.endif
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-amd64
mailing list