It doesn't always fail, and I tried to mitigate this by disabling ASLR.
Michael Hope noticed:
"The fault occurs as the 'pass' value given to longjmp() gets corrupted before
use by setjmp(), causing the 'setjmp() < 2' test to fail and the system to loop
forever. The only assembler level fortify/non-fortify difference is a call to
longjmp_chk instead of longjmp.
Note that shifting 'mystack' off the stack and into static memory also works
around the problem.
glibc-2.11.1/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S is broken. It
saves the value of 'pass' in ecx for later use but ecx is trashed by a syscall.
The syscall is used to bring in the signal stack so that the fortify code can
print an error message if needed. The problem goes away with -U_FORTIFY_SOURCE
as no such syscall is used."
Created attachment 4962
reproducer
Here is the reproducer. This dies on alarm on Ubuntu x86_64 (eglibc 2.11 and
2.12) and Fedora x86_64 (2.12) when using more recent glibc:
$ gcc -O2 -fno-stack- protector -D_FORTIFY_SOURCE=2 -Wall minimal.c -o minimal
/tmp
$ ./minimal
Alarm Clock
It doesn't always fail, and I tried to mitigate this by disabling ASLR.
Michael Hope noticed:
"The fault occurs as the 'pass' value given to longjmp() gets corrupted before
use by setjmp(), causing the 'setjmp() < 2' test to fail and the system to loop
forever. The only assembler level fortify/non-fortify difference is a call to
longjmp_chk instead of longjmp.
Note that shifting 'mystack' off the stack and into static memory also works
around the problem.
glibc-2. 11.1/sysdeps/ unix/sysv/ linux/x86_ 64/____ longjmp_ chk.S is broken. It
saves the value of 'pass' in ecx for later use but ecx is trashed by a syscall.
The syscall is used to bring in the signal stack so that the fortify code can
print an error message if needed. The problem goes away with -U_FORTIFY_SOURCE
as no such syscall is used."