diff mbox

bootx_init.c:88: undefined reference to `__stack_chk_fail_local'

Message ID alpine.DEB.2.20.99.1701040957380.31470@trent.utfs.org (mailing list archive)
State Not Applicable
Headers show

Commit Message

Christian Kujau Jan. 4, 2017, 6:33 p.m. UTC
On Wed, 4 Jan 2017, Christophe LEROY wrote:
> Using GCC 5.4.0, I don't have that issue. bootx_init.o only contains reference
> to __stack_chk_fail

FWIW, building with a GCC 5.2 crosscompiler succeeds (with 
CONFIG_CC_STACKPROTECTOR_STRONG=y), but I don't know if it will boot 
though, see my other mail in this thread:

  https://lists.ozlabs.org/pipermail/linuxppc-dev/2017-January/152623.html

So, would the following be sufficient? It compiles, but I haven't had a 
chance to boot yet.




Thanks,
Christian.

Comments

Christian Kujau Jan. 10, 2017, 2:11 a.m. UTC | #1
On Wed, 4 Jan 2017, Christian Kujau wrote:
> So, would the following be sufficient? It compiles, but I haven't had a 
> chance to boot yet.
> 

So, with -fno-stack-protector my GCC 4.9.2 compiles with 
CC_STACKPROTECTOR_STRONG=y but panics during boot:


Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: c069278c
CPU: 0 PIP: 591 Comm: systemd Tainted: G       W      4.10.0-rc3-dirty
Call Trace:
[ee965bb0] [c0693f5c] panic+0x120/0x274 (unreliable)
[ee965c10] [c002c568] print_tainted+0x0/0xcc
[ee965c20] [c069278c] schedule_timeout+0x25c/0x280
[ee965c80] [c068cc30] io_schedule_timeout+0x90/0xf4
[ee965ca0] [c00ac870] wait_on_page_bit_killable+0x1Oc/0x170
[ee965cf0] [c00ad240] __lock_page_or_retry+0xd4/0x12c
[ee965d10] [c00ad708] filemap_fault+0x470/0x5b0
[ee965d60] [c00d07c8] __do_fault+0x2c/0x90
[ee965e40] [c00d4104] handle_mm__fault+0x7c0/0x9cc
[ee965e00] [c0015a6c] do_page_fault+0x2ec,0x5b4
[ee965e40] [c0011660] handle_page_fault+0xc/0x80
--- interrupt: 301 at do_page_fault+0x394/0x5b4
    LR = do_page_fault+0x378,0x5b4
[ee965f00] [c0015c04] do_page_fault+0x484/0x5b4 (unreliable)
[ee965f40] [c0011660] handle_page_fault+0xc/0x80
--- interrupt: 401 at 0x2074d000
    LR = 0x207cff0


Maybe ppc32 is not supposed to be built with CC_STACKPROTECTOR ?

Thanks,
Christian.

> 
> diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
> index 1eb7b45..c7dcab9 100644
> --- a/arch/powerpc/platforms/powermac/Makefile
> +++ b/arch/powerpc/platforms/powermac/Makefile
> @@ -1,4 +1,4 @@
> -CFLAGS_bootx_init.o  		+= -fPIC
> +CFLAGS_bootx_init.o  		+= -fPIC -fno-stack-protector
>  
>  ifdef CONFIG_FUNCTION_TRACER
>  # Do not trace early boot code
> 
> 
> Thanks,
> Christian.
> -- 
> BOFH excuse #156:
> 
> Zombie processes haunting the computer
>
Benjamin Herrenschmidt Jan. 10, 2017, 4:32 a.m. UTC | #2
On Mon, 2017-01-09 at 18:11 -0800, Christian Kujau wrote:
> So, with -fno-stack-protector my GCC 4.9.2 compiles with 
> CC_STACKPROTECTOR_STRONG=y but panics during boot:

How can it make any sense to have -fno-stack-protector and
CC_STACKPROTECTOR_STRONG=y at the same time ?

Ben.
Christophe Leroy Jan. 10, 2017, 6:26 a.m. UTC | #3
Le 10/01/2017 à 03:11, Christian Kujau a écrit :
> On Wed, 4 Jan 2017, Christian Kujau wrote:
>> So, would the following be sufficient? It compiles, but I haven't had a
>> chance to boot yet.
>>
>
> So, with -fno-stack-protector my GCC 4.9.2 compiles with
> CC_STACKPROTECTOR_STRONG=y but panics during boot:
>
>
>
> Maybe ppc32 is not supposed to be built with CC_STACKPROTECTOR ?

Indeed, the latest versions of GCC don't use anymore the global variable 
__stack_chk_guard as canary value, but a value stored at -0x7008(r2). 
This is not compatible with the current implementation of  the kernel 
with uses r2 as a pointeur to current task struct.
So until we fix it, I don't think CC_STACKPROTECTOR is usable on PPC 
with modern versions of GCC.

Christophe

>
> Thanks,
> Christian.
>
>>
>> diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
>> index 1eb7b45..c7dcab9 100644
>> --- a/arch/powerpc/platforms/powermac/Makefile
>> +++ b/arch/powerpc/platforms/powermac/Makefile
>> @@ -1,4 +1,4 @@
>> -CFLAGS_bootx_init.o  		+= -fPIC
>> +CFLAGS_bootx_init.o  		+= -fPIC -fno-stack-protector
>>
>>  ifdef CONFIG_FUNCTION_TRACER
>>  # Do not trace early boot code
>>
>>
>> Thanks,
>> Christian.
>> --
>> BOFH excuse #156:
>>
>> Zombie processes haunting the computer
>>
>
Christian Kujau Jan. 10, 2017, 6:46 p.m. UTC | #4
On Mon, 9 Jan 2017, Benjamin Herrenschmidt wrote:
> On Mon, 2017-01-09 at 18:11 -0800, Christian Kujau wrote:
> > So, with -fno-stack-protector my GCC 4.9.2 compiles with 
> > CC_STACKPROTECTOR_STRONG=y but panics during boot:
> 
> How can it make any sense to have -fno-stack-protector and
> CC_STACKPROTECTOR_STRONG=y at the same time ?

I've set -fno-stack-protector only for bootx_init.c, as laid out in the 
diff I posted. This way the kernel at least compiled.

Thanks,
Christian.
Segher Boessenkool Jan. 11, 2017, 10:54 p.m. UTC | #5
On Tue, Jan 10, 2017 at 07:26:15AM +0100, Christophe LEROY wrote:
> >Maybe ppc32 is not supposed to be built with CC_STACKPROTECTOR ?
> 
> Indeed, the latest versions of GCC don't use anymore the global variable 
> __stack_chk_guard as canary value, but a value stored at -0x7008(r2). 
> This is not compatible with the current implementation of  the kernel 
> with uses r2 as a pointeur to current task struct.
> So until we fix it, I don't think CC_STACKPROTECTOR is usable on PPC 
> with modern versions of GCC.

I still wonder what changed.  Nothing relevant has changed for ten years
or whatever as far as I see; unless it is just the -fstack-protector-strong
that makes it fail now.  Curious.


Segher
Christophe Leroy Jan. 12, 2017, 7:52 a.m. UTC | #6
Le 11/01/2017 à 23:54, Segher Boessenkool a écrit :
> On Tue, Jan 10, 2017 at 07:26:15AM +0100, Christophe LEROY wrote:
>>> Maybe ppc32 is not supposed to be built with CC_STACKPROTECTOR ?
>>
>> Indeed, the latest versions of GCC don't use anymore the global variable
>> __stack_chk_guard as canary value, but a value stored at -0x7008(r2).
>> This is not compatible with the current implementation of  the kernel
>> with uses r2 as a pointeur to current task struct.
>> So until we fix it, I don't think CC_STACKPROTECTOR is usable on PPC
>> with modern versions of GCC.
>
> I still wonder what changed.  Nothing relevant has changed for ten years
> or whatever as far as I see; unless it is just the -fstack-protector-strong
> that makes it fail now.  Curious.
>

Yes, looks like it was changed from global to TLS in 2005 on powerpc. 
Indeed when I implemented STACKPROTECTOR in Kernel on ppc I 
copied/pasted it from ARM which is (still?) using the global 
__stack_chk_guard, and at first it worked quite well on my powerpc.

x86 has the following option on GCC. Couldn't we have it on powerpc too ?

-mstack-protector-guard=guard
Generate  stack  protection  code  using  canary  at
guard.   Supported  locations are ‘ global ’ for global canary or ‘ tls
’ for per-thread canary in the TLS block (the  default). This  option 
has  effect  only  when  ‘-fstack-protector’  or ‘-fstack-protector-all’ 
is specified.

Christophe
Christophe Leroy Jan. 12, 2017, 2:42 p.m. UTC | #7
Le 12/01/2017 à 08:52, Christophe LEROY a écrit :
>
>
> Le 11/01/2017 à 23:54, Segher Boessenkool a écrit :
>> On Tue, Jan 10, 2017 at 07:26:15AM +0100, Christophe LEROY wrote:
>>>> Maybe ppc32 is not supposed to be built with CC_STACKPROTECTOR ?
>>>
>>> Indeed, the latest versions of GCC don't use anymore the global variable
>>> __stack_chk_guard as canary value, but a value stored at -0x7008(r2).
>>> This is not compatible with the current implementation of  the kernel
>>> with uses r2 as a pointeur to current task struct.
>>> So until we fix it, I don't think CC_STACKPROTECTOR is usable on PPC
>>> with modern versions of GCC.
>>
>> I still wonder what changed.  Nothing relevant has changed for ten years
>> or whatever as far as I see; unless it is just the
>> -fstack-protector-strong
>> that makes it fail now.  Curious.
>>
>
> Yes, looks like it was changed from global to TLS in 2005 on powerpc.
> Indeed when I implemented STACKPROTECTOR in Kernel on ppc I
> copied/pasted it from ARM which is (still?) using the global
> __stack_chk_guard, and at first it worked quite well on my powerpc.
>
> x86 has the following option on GCC. Couldn't we have it on powerpc too ?
>
> -mstack-protector-guard=guard
> Generate  stack  protection  code  using  canary  at
> guard.   Supported  locations are ‘ global ’ for global canary or ‘ tls
> ’ for per-thread canary in the TLS block (the  default). This  option
> has  effect  only  when  ‘-fstack-protector’  or ‘-fstack-protector-all’
> is specified.
>

Finally, it looks like it is not so easy.

I have three instances of GCC:
* 4.4.4, home built
* 4.6.3, from https://www.kernel.org/pub/tools/crosstool/
* 4.8.3, home built

The 4.6.3 uses __stack_chk_guard, while the 4.4.4 and 4.8.3 use -28680(r2)

Is it dependent on the way GCC is built ? Then do we have a way to know, 
when we compile, which method GCC will use ?

See details below for each of the 3 GCC versions.

Christophe

Using built-in specs.
Target: ppc-linux
Configured with: /root/cldk/gcc-4.4.4/configure --target=ppc-linux 
--with-headers=yes --with-cpu=860 --prefix=/opt/cldk 
--bindir=/opt/cldk/bin --sbindir=/opt/cldk/sbin 
--libexecdir=/opt/cldk/libexec --datadir=/opt/cldk/share 
--sysconfdir=/opt/cldk/etc --libdir=/opt/cldk/lib 
--includedir=/opt/cldk/usr/include --oldincludedir=/opt/cldk/usr/include 
--infodir=/opt/cldk/share/info --mandir=/opt/cldk/share/man 
--enable-languages=c,c++
Thread model: posix
gcc version 4.4.4 (GCC)

0000007c <name_to_dev_t>:
   7c:	7c 08 02 a6 	mflr    r0
   80:	94 21 ff a0 	stwu    r1,-96(r1)
   84:	3c 80 00 00 	lis     r4,0
			86: R_PPC_ADDR16_HA	.rodata.str1.4+0x1bc
   88:	93 c1 00 58 	stw     r30,88(r1)
   8c:	93 e1 00 5c 	stw     r31,92(r1)
   90:	90 01 00 64 	stw     r0,100(r1)
   94:	93 81 00 50 	stw     r28,80(r1)
   98:	93 a1 00 54 	stw     r29,84(r1)
   9c:	38 84 01 bc 	addi    r4,r4,444
			9e: R_PPC_ADDR16_LO	.rodata.str1.4+0x1bc
   a0:	38 a0 00 09 	li      r5,9
   a4:	80 02 8f f8 	lwz     r0,-28680(r2)
   a8:	90 01 00 4c 	stw     r0,76(r1)

[...]

   fc:	80 01 00 4c 	lwz     r0,76(r1)
  100:	81 22 8f f8 	lwz     r9,-28680(r2)
  104:	7c 00 4a 79 	xor.    r0,r0,r9
  108:	39 20 00 00 	li      r9,0
  10c:	7f a3 eb 78 	mr      r3,r29
  110:	40 82 03 88 	bne-    498 <name_to_dev_t+0x41c>

[...]

  498:	48 00 00 01 	bl      498 <name_to_dev_t+0x41c>
			498: R_PPC_REL24	__stack_chk_fail


Using built-in specs.
COLLECT_GCC=powerpc64-linux-gcc
COLLECT_LTO_WRAPPER=/opt/gcc-4.6.3-nolibc/powerpc64-linux/bin/../libexec/gcc/powerpc64-linux/4.6.3/lto-wrapper
Target: powerpc64-linux
Configured with: /home/tony/buildall/src/gcc/configure 
--target=powerpc64-linux --host=i686-linux-gnu --build=i686-linux-gnu 
--enable-targets=all 
--prefix=/opt/cross/gcc-4.6.3-nolibc/powerpc64-linux/ 
--enable-languages=c --with-newlib --without-headers 
--enable-sjlj-exceptions --with-system-libunwind --disable-nls 
--disable-threads --disable-shared --disable-libmudflap --disable-libssp 
--disable-libgomp --disable-decimal-float --enable-checking=release 
--with-mpfr=/home/tony/buildall/src/sys-i686 
--with-gmp=/home/tony/buildall/src/sys-i686 --disable-bootstrap 
--disable-libquadmath
Thread model: single
gcc version 4.6.3 (GCC)

000000c0 <name_to_dev_t>:
   c0:	94 21 ff a0 	stwu    r1,-96(r1)
   c4:	7c 08 02 a6 	mflr    r0
   c8:	3c 80 00 00 	lis     r4,0
			ca: R_PPC_ADDR16_HA	.rodata.str1.4+0x50
   cc:	38 a0 00 09 	li      r5,9
   d0:	38 84 00 50 	addi    r4,r4,80
			d2: R_PPC_ADDR16_LO	.rodata.str1.4+0x50
   d4:	bf 81 00 50 	stmw    r28,80(r1)
   d8:	3f e0 00 00 	lis     r31,0
			da: R_PPC_ADDR16_HA	__stack_chk_guard
   dc:	7c 7e 1b 78 	mr      r30,r3
   e0:	90 01 00 64 	stw     r0,100(r1)
   e4:	3b ff 00 00 	addi    r31,r31,0
			e6: R_PPC_ADDR16_LO	__stack_chk_guard
   e8:	80 1f 00 00 	lwz     r0,0(r31)
   ec:	90 01 00 4c 	stw     r0,76(r1)

[...]

  13c:	81 21 00 4c 	lwz     r9,76(r1)
  140:	80 1f 00 00 	lwz     r0,0(r31)
  144:	7d 29 02 79 	xor.    r9,r9,r0
  148:	38 00 00 00 	li      r0,0
  14c:	7f 83 e3 78 	mr      r3,r28
  150:	40 82 03 68 	bne-    4b8 <name_to_dev_t+0x3f8>

[...]

  4b8:	48 00 00 01 	bl      4b8 <name_to_dev_t+0x3f8>
			4b8: R_PPC_REL24	__stack_chk_fail


Using built-in specs.
COLLECT_GCC=ppc-linux-gcc
COLLECT_LTO_WRAPPER=/opt/cldk/libexec/gcc/ppc-linux/4.8.3/lto-wrapper
Target: ppc-linux
Configured with: /root/cldk/gcc-4.8.3/configure --target=ppc-linux 
--with-headers=yes --with-cpu=860 --prefix=/opt/cldk 
--bindir=/opt/cldk/bin --sbindir=/opt/cldk/sbin 
--libexecdir=/opt/cldk/libexec --datadir=/opt/cldk/share 
--sysconfdir=/opt/cldk/etc --libdir=/opt/cldk/lib 
--includedir=/opt/cldk/usr/include --oldincludedir=/opt/cldk/usr/include 
--infodir=/opt/cldk/share/info --mandir=/opt/cldk/share/man 
--enable-languages=c,c++
Thread model: posix
gcc version 4.8.3 (GCC)

000000b0 <name_to_dev_t>:
   b0:	7c 08 02 a6 	mflr    r0
   b4:	94 21 ff a0 	stwu    r1,-96(r1)
   b8:	3c 80 00 00 	lis     r4,0
			ba: R_PPC_ADDR16_HA	.rodata.str1.4+0x50
   bc:	bf a1 00 54 	stmw    r29,84(r1)
   c0:	90 01 00 64 	stw     r0,100(r1)
   c4:	38 84 00 00 	addi    r4,r4,0
			c6: R_PPC_ADDR16_LO	.rodata.str1.4+0x50
   c8:	38 a0 00 09 	li      r5,9
   cc:	7c 7f 1b 78 	mr      r31,r3
   d0:	81 22 8f f8 	lwz     r9,-28680(r2)
   d4:	91 21 00 4c 	stw     r9,76(r1)

[...]

  124:	81 41 00 4c 	lwz     r10,76(r1)
  128:	81 22 8f f8 	lwz     r9,-28680(r2)
  12c:	7d 4a 4a 79 	xor.    r10,r10,r9
  130:	39 20 00 00 	li      r9,0
  134:	40 82 03 70 	bne     4a4 <name_to_dev_t+0x3f4>

[...]

  4a4:	48 00 00 01 	bl      4a4 <name_to_dev_t+0x3f4>
			4a4: R_PPC_REL24	__stack_chk_fail
Benjamin Herrenschmidt Jan. 12, 2017, 3:20 p.m. UTC | #8
On Thu, 2017-01-12 at 15:42 +0100, Christophe LEROY wrote:
> The 4.6.3 uses __stack_chk_guard, while the 4.4.4 and 4.8.3 use
> -28680(r2)
> 
> Is it dependent on the way GCC is built ? Then do we have a way to
> know, 
> when we compile, which method GCC will use ?
> 
> See details below for each of the 3 GCC versions.

I think it depends if you built it along with glibc (so it can produce
userspace binaries) or not.

Cheers,
Ben.
Segher Boessenkool Jan. 12, 2017, 6:07 p.m. UTC | #9
On Thu, Jan 12, 2017 at 09:20:47AM -0600, Benjamin Herrenschmidt wrote:
> On Thu, 2017-01-12 at 15:42 +0100, Christophe LEROY wrote:
> > The 4.6.3 uses __stack_chk_guard, while the 4.4.4 and 4.8.3 use
> > -28680(r2)
> > 
> > Is it dependent on the way GCC is built ? Then do we have a way to
> > know, 
> > when we compile, which method GCC will use ?
> > 
> > See details below for each of the 3 GCC versions.
> 
> I think it depends if you built it along with glibc (so it can produce
> userspace binaries) or not.

Right.  Tony's compilers are built using a (modified version of) buildall,
and buildall goes out of its way to build without libc whatsoever, even
if the configuration (powerpc64-linux, for example) expects one.

Which leads to TARGET_LIBC_PROVIDES_SSP being undefined (it would normally
be true for glibc >= 2.4), and that is all.  Mystery solved.  Thanks!


Segher
Christophe Leroy Jan. 13, 2017, 12:15 p.m. UTC | #10
Le 12/01/2017 à 19:07, Segher Boessenkool a écrit :
> On Thu, Jan 12, 2017 at 09:20:47AM -0600, Benjamin Herrenschmidt wrote:
>> On Thu, 2017-01-12 at 15:42 +0100, Christophe LEROY wrote:
>>> The 4.6.3 uses __stack_chk_guard, while the 4.4.4 and 4.8.3 use
>>> -28680(r2)
>>>
>>> Is it dependent on the way GCC is built ? Then do we have a way to
>>> know,
>>> when we compile, which method GCC will use ?
>>>
>>> See details below for each of the 3 GCC versions.
>>
>> I think it depends if you built it along with glibc (so it can produce
>> userspace binaries) or not.
>
> Right.  Tony's compilers are built using a (modified version of) buildall,
> and buildall goes out of its way to build without libc whatsoever, even
> if the configuration (powerpc64-linux, for example) expects one.
>
> Which leads to TARGET_LIBC_PROVIDES_SSP being undefined (it would normally
> be true for glibc >= 2.4), and that is all.  Mystery solved.  Thanks!
>

Is there a way to know during compilation how the compiler will behave, 
in order to select the correct method ?

I have drafted a new approach in the kernel that uses -0x7008(r2) 
instead of the global __stack_chk_guard, but how can I select the proper 
approach during kernel compilation in line with the selected GCC ?

Christophe
David Laight Jan. 13, 2017, 12:23 p.m. UTC | #11
From: Christophe LEROY
> Sent: 13 January 2017 12:15
...
> > Which leads to TARGET_LIBC_PROVIDES_SSP being undefined (it would normally
> > be true for glibc >= 2.4), and that is all.  Mystery solved.  Thanks!
> >
> 
> Is there a way to know during compilation how the compiler will behave,
> in order to select the correct method ?
> 
> I have drafted a new approach in the kernel that uses -0x7008(r2)
> instead of the global __stack_chk_guard, but how can I select the proper
> approach during kernel compilation in line with the selected GCC ?

Worse, how can you ensure that loadable modules are compiled with the
same option as the rest of the kernel.

	David
diff mbox

Patch

diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index 1eb7b45..c7dcab9 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -1,4 +1,4 @@ 
-CFLAGS_bootx_init.o  		+= -fPIC
+CFLAGS_bootx_init.o  		+= -fPIC -fno-stack-protector
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace early boot code