https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66491
Bug ID: 66491 Summary: x86_64 target cross-compiler generates stack protector code unsuitable for the Linux kernel if the compiler wasn't built against a C library Product: gcc Version: 5.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: dhowells at redhat dot com Target Milestone: --- The Fedora gcc-5.1.1 cross-compiler targeting x86_64 doesn't generate appropriate stack protection code as the compiler wasn't built against glibc. For example, if the following command is run: echo "int foo(void) { char X[200]; return 3; }" | x86_64-linux-gnu-gcc -S -x c -c -O0 -mcmodel=kernel -fstack-protector - -o - the code generated refers to __stack_chk_guard: ... movq __stack_chk_guard(%rip), %rax movq %rax, -8(%rbp) xorl %eax, %eax movl $3, %eax movq -8(%rbp), %rdx xorq __stack_chk_guard(%rip), %rdx je .L3 call __stack_chk_fail ... but it should instead use the %gs segment register to access the canary: ... movq %gs:40, %rax movq %rax, -8(%rbp) xorl %eax, %eax movl $3, %eax movq -8(%rbp), %rdx xorq %gs:40, %rdx je .L3 call __stack_chk_fail ... as is expected by the kernel. This was originally logged in the Red Hat bugzilla as: https://bugzilla.redhat.com/show_bug.cgi?id=1228800 The reporter looked into how cross-gcc is built and the problem seems to be this: gcc is configured with "--without-headers". The configure script checks for whether the target libc provides SSP (TARGET_LIBC_PROVIDES_SSP). In this case it will be false. The definition of TARGET_THREAD_SSP_OFFSET is conditional under "#ifdef TARGET_LIBC_PROVIDES_SSP" (in gcc/config/i386/gnu-user64.h), so it will not be defined. config/i386/i386.md describes how to generate stack protector code. It will use TLS canary only if "#ifdef TARGET_THREAD_SSP_OFFSET". As per one of the reporter's suggestions, -mcmodel=kernel should perhaps switch to the %gs method, overriding anything the gcc selects based on the C library.