gcc
gcc copied to clipboard
Use the illumos libc SSP implementation for -fstack-protector (9.3.0)
With this patch applied, and with the compiler configured to output 64-bit objects by default:
% gcc -dumpspecs | grep -A3 link_ssp
*link_ssp:
%{fstack-protector|fstack-protector-all|fstack-protector-strong|fstack-protector-explicit:%{m32:%{fpie|fPIE|fpic|fPIC:-lssp_ns}}}
When configured to output 32-bit objects by default, this looks as follows: (This is from gcc7 built with the same patch - gcc7 on OmniOS produces 32-bit by default)
*link_ssp:
%{fstack-protector|fstack-protector-all|fstack-protector-strong|fstack-protector-explicit:%{!m64:%{fpie|fPIE|fpic|fPIC:-lssp_ns}}}
Testing so far has been with this small program:
#include <stdio.h>
#include <string.h>
const char* buffer_long = "This is a long long string";
void
stack_overflows_here(void)
{
char buffer_short[20];
strcpy(buffer_short, buffer_long);
printf("Overflow triggered.\n");
}
int
main(void)
{
printf("Starting ");
#ifdef _LP64
printf("64-bit ");
#else
printf("32-bit ");
#endif
#ifdef __pic__
printf("- PIC: %d ", __pic__);
#endif
#ifdef __pie__
printf("- PIE: %d ", __pie__);
#endif
printf("\n");
stack_overflows_here();
return 0;
}
and the following test driver script
#!/bin/ksh
o="-fstack-protector"
function check {
typeset f="$1"
echo "*** $f"
nm $f | grep __stack_chk | cut -d'|' -f3-
[[ $f = *.o ]] && return
(./$f) && banner "$f DID NOT CRASH"
}
for b in 32 64; do
for f in "" pic PIC pie PIE; do
echo "******"
echo "****** $b $f"
echo "******"
[ -n "$f" ] && fopt="-f$f" || fopt=
op=overflow-$b-$f
gcc -m$b $o $fopt -o $op overflow.c
check $op
op=overflow-$b-$f.o
gcc -m$b $o $fopt -o $op -c overflow.c
check $op
op=overflow-$b-$f-2stage
gcc -m$b $o $fopt -o $op overflow-$b-$f.o
check overflow-$b-$f-2stage
op=overflow-$b-$f-2stage-nosplink
gcc -m$b $fopt -o $op overflow-$b-$f.o
# Expect link failure for 32-bit pic/pie case
if [ $b != 32 -o -z "$f" ]; then
check $op
else
# Test again and link with ssp_ns
gcc -m$b $fopt -o $op overflow-$b-$f.o -lssp_ns
check $op
fi
op=overflow-$b-$f-2stage-ld
ld -$b -o overflow-$b-$f-2stage-ld overflow-$b-$f.o -lc
# Expect link failure for 32-bit pic/pie case
if [ $b != 32 -o -z "$f" ]; then
check $op
else
# Test again and link the correct object
ld -$b -o overflow-$b-$f-2stage-ld overflow-$b-$f.o \
-lc -l ssp_ns
check $op
fi
echo
done
echo
done
which is producing the expected output. Showing that the __stack_chk_fail_local symbol only comes into play for 32-bit PIC objects, and that gcc does the right thing when linking those objects.
******
****** 32
******
*** overflow-32-
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
4|OBJT |GLOB |0 |24 |__stack_chk_guard
./test[23]: check: line 10: 3885: Abort(coredump)
*** overflow-32-.o
0|NOTY |GLOB |0 |UNDEF |__stack_chk_fail
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-32--2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
4|OBJT |GLOB |0 |24 |__stack_chk_guard
./test[31]: check: line 10: 3897: Abort(coredump)
*** overflow-32--2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
4|OBJT |GLOB |0 |24 |__stack_chk_guard
./test[37]: check: line 10: 3904: Abort(coredump)
*** overflow-32--2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
4|OBJT |GLOB |0 |17 |__stack_chk_guard
./test[48]: check: line 10: 3909: Abort(coredump)
******
****** 32 pic
******
*** overflow-32-pic
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[23]: check: line 10: 3918: Abort(coredump)
*** overflow-32-pic.o
0|NOTY |GLOB |2 |UNDEF |__stack_chk_fail_local
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-32-pic-2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[31]: check: line 10: 3930: Abort(coredump)
Undefined first referenced
symbol in file
__stack_chk_fail_local overflow-32-pic.o (symbol scope specifies local binding)
ld: fatal: symbol referencing errors. No output written to overflow-32-pic-2stage-nosplink
collect2: error: ld returned 1 exit status
*** overflow-32-pic-2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[41]: check: line 10: 3940: Abort(coredump)
Undefined first referenced
symbol in file
__stack_chk_fail_local overflow-32-pic.o (symbol scope specifies local binding)
ld: fatal: symbol referencing errors. No output written to overflow-32-pic-2stage-ld
*** overflow-32-pic-2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |12 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[53]: check: line 10: 3946: Abort(coredump)
******
****** 32 PIC
******
*** overflow-32-PIC
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[23]: check: line 10: 3955: Abort(coredump)
*** overflow-32-PIC.o
0|NOTY |GLOB |2 |UNDEF |__stack_chk_fail_local
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-32-PIC-2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[31]: check: line 10: 3967: Abort(coredump)
Undefined first referenced
symbol in file
__stack_chk_fail_local overflow-32-PIC.o (symbol scope specifies local binding)
ld: fatal: symbol referencing errors. No output written to overflow-32-PIC-2stage-nosplink
collect2: error: ld returned 1 exit status
*** overflow-32-PIC-2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[41]: check: line 10: 3977: Abort(coredump)
Undefined first referenced
symbol in file
__stack_chk_fail_local overflow-32-PIC.o (symbol scope specifies local binding)
ld: fatal: symbol referencing errors. No output written to overflow-32-PIC-2stage-ld
*** overflow-32-PIC-2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |12 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[53]: check: line 10: 3983: Abort(coredump)
******
****** 32 pie
******
*** overflow-32-pie
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[23]: check: line 10: 3992: Abort(coredump)
*** overflow-32-pie.o
0|NOTY |GLOB |2 |UNDEF |__stack_chk_fail_local
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-32-pie-2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[31]: check: line 10: 4004: Abort(coredump)
Undefined first referenced
symbol in file
__stack_chk_fail_local overflow-32-pie.o (symbol scope specifies local binding)
ld: fatal: symbol referencing errors. No output written to overflow-32-pie-2stage-nosplink
collect2: error: ld returned 1 exit status
*** overflow-32-pie-2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[41]: check: line 10: 4014: Abort(coredump)
Undefined first referenced
symbol in file
__stack_chk_fail_local overflow-32-pie.o (symbol scope specifies local binding)
ld: fatal: symbol referencing errors. No output written to overflow-32-pie-2stage-ld
*** overflow-32-pie-2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |12 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[53]: check: line 10: 4020: Abort(coredump)
******
****** 32 PIE
******
*** overflow-32-PIE
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[23]: check: line 10: 4029: Abort(coredump)
*** overflow-32-PIE.o
0|NOTY |GLOB |2 |UNDEF |__stack_chk_fail_local
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-32-PIE-2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[31]: check: line 10: 4041: Abort(coredump)
Undefined first referenced
symbol in file
__stack_chk_fail_local overflow-32-PIE.o (symbol scope specifies local binding)
ld: fatal: symbol referencing errors. No output written to overflow-32-PIE-2stage-nosplink
collect2: error: ld returned 1 exit status
*** overflow-32-PIE-2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |13 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[41]: check: line 10: 4051: Abort(coredump)
Undefined first referenced
symbol in file
__stack_chk_fail_local overflow-32-PIE.o (symbol scope specifies local binding)
ld: fatal: symbol referencing errors. No output written to overflow-32-PIE-2stage-ld
*** overflow-32-PIE-2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
29|FUNC |LOCL |2 |12 |__stack_chk_fail_local
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[53]: check: line 10: 4057: Abort(coredump)
******
****** 64
******
*** overflow-64-
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
8|OBJT |GLOB |0 |24 |__stack_chk_guard
./test[23]: check: line 10: 4066: Abort(coredump)
*** overflow-64-.o
0|NOTY |GLOB |0 |UNDEF |__stack_chk_fail
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-64--2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
8|OBJT |GLOB |0 |24 |__stack_chk_guard
./test[31]: check: line 10: 4078: Abort(coredump)
*** overflow-64--2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
8|OBJT |GLOB |0 |24 |__stack_chk_guard
./test[37]: check: line 10: 4085: Abort(coredump)
*** overflow-64--2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
8|OBJT |GLOB |0 |19 |__stack_chk_guard
./test[48]: check: line 10: 4090: Abort(coredump)
******
****** 64 pic
******
*** overflow-64-pic
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[23]: check: line 10: 4099: Abort(coredump)
*** overflow-64-pic.o
0|NOTY |GLOB |0 |UNDEF |__stack_chk_fail
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-64-pic-2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[31]: check: line 10: 4111: Abort(coredump)
*** overflow-64-pic-2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[37]: check: line 10: 4118: Abort(coredump)
*** overflow-64-pic-2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[48]: check: line 10: 4123: Abort(coredump)
******
****** 64 PIC
******
*** overflow-64-PIC
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[23]: check: line 10: 4132: Abort(coredump)
*** overflow-64-PIC.o
0|NOTY |GLOB |0 |UNDEF |__stack_chk_fail
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-64-PIC-2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[31]: check: line 10: 4144: Abort(coredump)
*** overflow-64-PIC-2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[37]: check: line 10: 4151: Abort(coredump)
*** overflow-64-PIC-2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[48]: check: line 10: 4156: Abort(coredump)
******
****** 64 pie
******
*** overflow-64-pie
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[23]: check: line 10: 4165: Abort(coredump)
*** overflow-64-pie.o
0|NOTY |GLOB |0 |UNDEF |__stack_chk_fail
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-64-pie-2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[31]: check: line 10: 4177: Abort(coredump)
*** overflow-64-pie-2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[37]: check: line 10: 4184: Abort(coredump)
*** overflow-64-pie-2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[48]: check: line 10: 4189: Abort(coredump)
******
****** 64 PIE
******
*** overflow-64-PIE
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[23]: check: line 10: 4198: Abort(coredump)
*** overflow-64-PIE.o
0|NOTY |GLOB |0 |UNDEF |__stack_chk_fail
0|NOTY |GLOB |0 |UNDEF |__stack_chk_guard
*** overflow-64-PIE-2stage
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[31]: check: line 10: 4210: Abort(coredump)
*** overflow-64-PIE-2stage-nosplink
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[37]: check: line 10: 4217: Abort(coredump)
*** overflow-64-PIE-2stage-ld
0|FUNC |GLOB |0 |UNDEF |__stack_chk_fail
0|OBJT |GLOB |0 |UNDEF |__stack_chk_guard
./test[48]: check: line 10: 4222: Abort(coredump)
Do we have test suite results for this?