Bug 85644

Summary: [8 Regression] -fstack-protector generates invalid read to %fs:0x0 on mac
Product: gcc Reporter: URABE, Shyouhei <shyouhei>
Component: targetAssignee: Jakub Jelinek <jakub>
Status: RESOLVED FIXED    
Severity: normal CC: mark.hsj
Priority: P3 Keywords: wrong-code
Version: 9.0   
Target Milestone: 8.3   
Host: Target: x86_64-darwin
Build: Known to work:
Known to fail: Last reconfirmed: 2018-08-13 00:00:00
Bug Depends on:    
Bug Blocks: 86832    
Attachments: gcc9-pr85644.patch

Description URABE, Shyouhei 2018-05-04 00:57:11 UTC
When -fstack-protector is passed, gcc introduces problematic %fs:0x0 reference in a function prelude.

% echo 'int main(void) { char c[8]; }' | gcc-trunk -v -fstack-protector -xc -
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/Users/urabe.shyouhei/target/libexec/gcc/x86_64-apple-darwin15.6.0/9.0.0/lto-wrapper
Target: x86_64-apple-darwin15.6.0
Configured with: /Users/urabe.shyouhei/data/src/github.com/gcc-mirror/gcc/configure --prefix=/Users/urabe.shyouhei/target --program-suffix=-trunk --enable-languages=c --disable-bootstrap --cache-file=/Users/urabe.shyouhei/data/build/gcc/config.cache
Thread model: posix
gcc version 9.0.0 20180503 (experimental) (GCC)
COLLECT_GCC_OPTIONS='-v' '-fstack-protector' '-mmacosx-version-min=10.11.0' '-asm_macosx_version_min=10.11' '-mtune=core2'
 /Users/urabe.shyouhei/target/libexec/gcc/x86_64-apple-darwin15.6.0/9.0.0/cc1 -quiet -v -D__DYNAMIC__ - -fPIC -quiet -dumpbase - -mmacosx-version-min=10.11.0 -mtune=core2 -auxbase - -version -fstack-protector -o /var/folders/50/9ss08lxs5ml7kvz614tr3_wmm17741/T//ccO4in0z.s
GNU C17 (GCC) version 9.0.0 20180503 (experimental) (x86_64-apple-darwin15.6.0)
        compiled by GNU C version 6.4.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP

GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
ignoring nonexistent directory "/Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0/../../../../x86_64-apple-darwin15.6.0/include"
#include "..." search starts here:
#include <...> search starts here:
 /Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0/include
 /usr/local/include
 /Users/urabe.shyouhei/target/include
 /Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0/include-fixed
 /usr/include
 /System/Library/Frameworks
 /Library/Frameworks
End of search list.
GNU C17 (GCC) version 9.0.0 20180503 (experimental) (x86_64-apple-darwin15.6.0)
        compiled by GNU C version 6.4.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP

GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 48d8373f46962ba1e7a1ba1886f038d5
COLLECT_GCC_OPTIONS='-v' '-fstack-protector' '-mmacosx-version-min=10.11.0'  '-mtune=core2'
 as -arch x86_64 -v -force_cpusubtype_ALL -mmacosx-version-min=10.11 -o /var/folders/50/9ss08lxs5ml7kvz614tr3_wmm17741/T//cc2AB2b1.o /var/folders/50/9ss08lxs5ml7kvz614tr3_wmm17741/T//ccO4in0z.s
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1as -triple x86_64-apple-macosx10.11.0 -filetype obj -main-file-name ccO4in0z.s -target-cpu core2 -fdebug-compilation-dir /Users/urabe.shyouhei/data/build/ruby@gcc-8/trunk@O0 -dwarf-debug-producer Apple LLVM version 8.0.0 (clang-800.0.42.1) -dwarf-version=2 -mrelocation-model pic -o /var/folders/50/9ss08lxs5ml7kvz614tr3_wmm17741/T//cc2AB2b1.o /var/folders/50/9ss08lxs5ml7kvz614tr3_wmm17741/T//ccO4in0z.s
COMPILER_PATH=/Users/urabe.shyouhei/target/libexec/gcc/x86_64-apple-darwin15.6.0/9.0.0/:/Users/urabe.shyouhei/target/libexec/gcc/x86_64-apple-darwin15.6.0/9.0.0/:/Users/urabe.shyouhei/target/libexec/gcc/x86_64-apple-darwin15.6.0/:/Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0/:/Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/
LIBRARY_PATH=/Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0/:/Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0/../../../
COLLECT_GCC_OPTIONS='-v' '-fstack-protector' '-mmacosx-version-min=10.11.0'  '-mtune=core2'
 /Users/urabe.shyouhei/target/libexec/gcc/x86_64-apple-darwin15.6.0/9.0.0/collect2 -dynamic -arch x86_64 -macosx_version_min 10.11.0 -weak_reference_mismatches non-weak -o a.out -L/Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0 -L/Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0/../../.. /var/folders/50/9ss08lxs5ml7kvz614tr3_wmm17741/T//cc2AB2b1.o -no_compact_unwind -lSystem -lgcc_ext.10.5 -lgcc -lSystem -v
collect2 version 9.0.0 20180503 (experimental)
/usr/bin/ld -dynamic -arch x86_64 -macosx_version_min 10.11.0 -weak_reference_mismatches non-weak -o a.out -L/Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0 -L/Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0/../../.. /var/folders/50/9ss08lxs5ml7kvz614tr3_wmm17741/T//cc2AB2b1.o -no_compact_unwind -lSystem -lgcc_ext.10.5 -lgcc -lSystem -v
@(#)PROGRAM:ld  PROJECT:ld64-274.1
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
Library search paths:
        /Users/urabe.shyouhei/target/lib/gcc/x86_64-apple-darwin15.6.0/9.0.0
        /Users/urabe.shyouhei/target/lib
        /usr/lib
        /usr/local/lib
Framework search paths:
        /Library/Frameworks/
        /System/Library/Frameworks/
 /usr/local/bin/gnm -n /var/folders/50/9ss08lxs5ml7kvz614tr3_wmm17741/T//cc2AB2b1.o
%
%
% gobjdump -S ./a.out

./a.out:     file format mach-o-x86-64


Disassembly of section .text:

0000000100000f5c <_main>:
   100000f5c:   55                      push   %rbp
   100000f5d:   48 89 e5                mov    %rsp,%rbp
   100000f60:   48 83 ec 10             sub    $0x10,%rsp
   100000f64:   64 48 8b 04 25 00 00    mov    %fs:0x0,%rax
   100000f6b:   00 00
   100000f6d:   48 89 45 f8             mov    %rax,-0x8(%rbp)
   100000f71:   31 c0                   xor    %eax,%eax
   100000f73:   b8 00 00 00 00          mov    $0x0,%eax
   100000f78:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
   100000f7c:   64 48 33 14 25 00 00    xor    %fs:0x0,%rdx
   100000f83:   00 00
   100000f85:   74 05                   je     100000f8c <_main+0x30>
   100000f87:   e8 02 00 00 00          callq  100000f8e <_main+0x32>
   100000f8c:   c9                      leaveq
   100000f8d:   c3                      retq

Disassembly of section __TEXT.__stubs:

0000000100000f8e <__TEXT.__stubs>:
   100000f8e:   ff 25 7c 00 00 00       jmpq   *0x7c(%rip)        # 100001010 <_main+0xb4>

Disassembly of section __TEXT.__stub_helper:

0000000100000f94 <__TEXT.__stub_helper>:
   100000f94:   4c 8d 1d 6d 00 00 00    lea    0x6d(%rip),%r11        # 100001008 <_main+0xac>
   100000f9b:   41 53                   push   %r11
   100000f9d:   ff 25 5d 00 00 00       jmpq   *0x5d(%rip)        # 100001000 <_main+0xa4>
   100000fa3:   90                      nop
   100000fa4:   68 00 00 00 00          pushq  $0x0
   100000fa9:   e9 e6 ff ff ff          jmpq   100000f94 <_main+0x38>
%
%
% lldb -- ./a.out
(lldb) target create "./a.out"
Current executable set to './a.out' (x86_64).
(lldb) run
Process 788 launched: './a.out' (x86_64)
Process 788 stopped
* thread #1: tid = 0x185625, 0x0000000100000f64 a.out`main + 8, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000100000f64 a.out`main + 8
a.out`main:
->  0x100000f64 <+8>:  movq   %fs:0x0, %rax
    0x100000f6d <+17>: movq   %rax, -0x8(%rbp)
    0x100000f71 <+21>: xorl   %eax, %eax
    0x100000f73 <+23>: movl   $0x0, %eax
(lldb) register read
General Purpose Registers:
       rax = 0x0000000100000f5c  a.out`main
       rbx = 0x0000000000000000
       rcx = 0x00007fff5fbfdf08
       rdx = 0x00007fff5fbfdc68
       rdi = 0x0000000000000001
       rsi = 0x00007fff5fbfdc58
       rbp = 0x00007fff5fbfdc30
       rsp = 0x00007fff5fbfdc20
        r8 = 0x0000000000000000
        r9 = 0x00007fff7640a0c8  atexit_mutex + 24
       r10 = 0x00000000ffffffff
       r11 = 0xffffffff00000000
       r12 = 0x0000000000000000
       r13 = 0x0000000000000000
       r14 = 0x0000000000000000
       r15 = 0x0000000000000000
       rip = 0x0000000100000f64  a.out`main + 8
    rflags = 0x0000000000010202
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb)
Comment 1 Andrew Pinski 2018-08-02 17:50:58 UTC
*** Bug 86762 has been marked as a duplicate of this bug. ***
Comment 2 Andrew Pinski 2018-08-13 06:28:14 UTC
.
Comment 3 Eric Gallager 2018-08-13 17:09:31 UTC
Some of the dups of this mentioned thread-local storage (TLS), in which case bug 29838 and bug 52268 might be related
Comment 4 Jakub Jelinek 2018-11-21 17:16:45 UTC
Created attachment 45060 [details]
gcc9-pr85644.patch

Untested fix.  I have no access to Darwin though.
Comment 5 Jakub Jelinek 2018-11-21 17:37:32 UTC
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86832#c7 for more details.
Comment 6 Jakub Jelinek 2018-11-22 09:49:34 UTC
Author: jakub
Date: Thu Nov 22 09:48:43 2018
New Revision: 266370

URL: https://gcc.gnu.org/viewcvs?rev=266370&root=gcc&view=rev
Log:
	PR target/85644
	PR target/86832
	* config/i386/i386.c (ix86_option_override_internal): Default
	ix86_stack_protector_guard to SSP_TLS only if TARGET_THREAD_SSP_OFFSET
	is defined.
	* config/i386/i386.md (stack_protect_set, stack_protect_set_<mode>,
	stack_protect_test, stack_protect_test_<mode>): Use empty condition
	instead of TARGET_SSP_TLS_GUARD.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/config/i386/i386.md
Comment 7 Jakub Jelinek 2018-11-22 10:19:39 UTC
Can somebody please test this on darwin (on the trunk)? Thanks.
Comment 8 Mark Harris 2018-11-24 19:11:53 UTC
Thanks for fixing this. I can confirm that with gcc trunk, -fstack-protector, -fstack-protector-all, and -fstack-protector-strong are now working for me on macOS 10.12.6, for both -m64 and -m32.
Comment 9 Jakub Jelinek 2019-01-08 09:57:08 UTC
Author: jakub
Date: Tue Jan  8 09:56:36 2019
New Revision: 267686

URL: https://gcc.gnu.org/viewcvs?rev=267686&root=gcc&view=rev
Log:
	Backported from mainline
	2018-11-22  Jakub Jelinek  <jakub@redhat.com>

	PR target/85644
	PR target/86832
	* config/i386/i386.c (ix86_option_override_internal): Default
	ix86_stack_protector_guard to SSP_TLS only if TARGET_THREAD_SSP_OFFSET
	is defined.
	* config/i386/i386.md (stack_protect_set, stack_protect_set_<mode>,
	stack_protect_test, stack_protect_test_<mode>): Use empty condition
	instead of TARGET_SSP_TLS_GUARD.

Modified:
    branches/gcc-8-branch/gcc/ChangeLog
    branches/gcc-8-branch/gcc/config/i386/i386.c
    branches/gcc-8-branch/gcc/config/i386/i386.md
Comment 10 Jakub Jelinek 2019-01-08 10:43:16 UTC
Fixed for 8.3+ too.