uclibc's nptl fails to build for arm with gcc-4.8 -fstack-check

Anthony G. Basile basile at opensource.dyc.edu
Sat Dec 27 20:51:46 UTC 2014

Hi everyone,

I hit a bug in all versions of uclibc when building for TARGET=arm using gcc-4.8.3 with -fstack-check.  This is a new option introduced in gcc-4.8 which checks that you don't go past the boundary of the stack in a *multithreaded* environment.  In a single threaded environment -fstack-protector and friends is sufficient.  This bug only affects arm as far as I can tell, and I had no problems with amd64, x86, mips or ppc.  I did not test other arches.

The build dies with the following in nptl code:

gcc -c libpthread/nptl/sysdeps/pthread/pt-crti.S -o libpthread/nptl/sysdeps/pthread/pt-crti.o -Wall -Wstrict-prototypes -Wstrict-aliasing -funsigned-char -fno-builtin -fno-asm -mlittle-endian -fstack-protector -nostdinc -I./include -I./include -include libc-symbols.h -I./libc/sysdeps/linux/arm -I./libc/sysdeps/linux -I./ldso/ldso/arm -I./ldso/include -I. -Os -fstrict-aliasing -D__USE_STDIO_FUTEXES__ -DHAVE_FORCED_UNWIND -D_LIBC_REENTRANT -I./libpthread/nptl -I./libpthread/nptl -I./libpthread/nptl/sysdeps/unix/sysv/linux/arm -I./libpthread/nptl/sysdeps/arm -I./libpthread/nptl/sysdeps/arm -I./libpthread/nptl/sysdeps/unix/sysv/linux -I./libpthread/nptl/sysdeps/unix/sysv/linux -I./libpthread/nptl/sysdeps/pthread -I./libpthread/nptl/sysdeps/pthread/bits -I./libpthread/nptl/sysdeps/generic -I./libc/sysdeps/linux/common -isystem /usr/lib/gcc/armv7a-hardfloat-linux-uclibceabi/4.8.3/include-fixed -isystem /usr/lib/gcc/armv7a-hardfloat-linux-uclibceabi/4.8.3/include -I/usr/include/ -DN
 libpthread/nptl/sysdeps/pthread/pt-crti.o -MD -MP -MF libpthread/nptl/sysdeps/pthread/.pt-crti.o.dep -D__ASSEMBLER__ -Wa,--noexecstack   -fPIC 
libpthread/nptl/sysdeps/pthread/pt-crti.S: Assembler messages:
libpthread/nptl/sysdeps/pthread/pt-crti.S:38: Error: undefined local label `.L10'
libpthread/nptl/sysdeps/pthread/pt-crti.S:62: Error: undefined local label `.L13'
libpthread/nptl/sysdeps/pthread/Makefile.in:76: recipe for target 'libpthread/nptl/sysdeps/pthread/pt-crti.o' failed
make: *** [libpthread/nptl/sysdeps/pthread/pt-crti.o] Error 1

What's going on here is a bad sed in libpthread/nptl/sysdeps/pthread/Makefile.in.  There we have

$(libpthread_pthread_OUT)/pt-crti.S: $(libpthread_pthread_OUT)/pt-initfini.s $(libpthread_pthread_OUT)/defs.h
        $(do_sed) -n -e '/[     ]*\.file/d' \
                -e '1,/@HEADER_ENDS/p' \
                -e '/@_.*_PROLOG_BEGINS/,/@_.*_PROLOG_ENDS/p' \
                -e '/@TRAILER_BEGINS/,$$p' $< > $@.tmp
        $(Q)mv $@.tmp $@

where pt-initfini.s is compiled from pt-initfini.c with -fstack-protector and -fstack-protector-all filtered out, but not -fstack-check.  What the sed does is it removes .L10 which lives between /*@_init_EPILOG_BEGINS*/ and /*@_init_EPILOG_ENDS*/ in pt-initfini.s, and similar for .L13 between _fini_EPILOG_BEINGS/ENDS.  But .L10 and .L13 are still referenced in the remaining code as

	ldr     r3, .L10

Its easy to just add -fstack-check along with -fstack-protector in the SSP_DISABLE_FLAGS in Rules.mak, but this bothers me because it does work for other arches and it does add more security albeit with some perf hit.  In fact, the only place you really need to add -fno-stack-check is where you build pt-initfini.c, and then only for arm.  Something like the following. (This is to just give you an idea as the flag really needs to be properly checked in Rules.mak).

 CFLAGS-pt-initfini.c = -S -g0 $(PICFLAG) -fno-inline-functions \
                        $(call check_gcc,-fno-unit-at-a-time,)  \
-                       $(SSP_DISABLE_FLAGS) \
+                       $(SSP_DISABLE_FLAGS) -fno-stack-check \
                        -finhibit-size-directive                        \
                        -fno-asynchronous-unwind-tables -fno-unwind-tables \
                        $(patsubst -f%,-fno-%,$(call check_gcc,-fexceptions,))

So before I submit a patch, I'm wonder what people think here?  Should we just go ahead an lump -fstack-check in with SSP_DISABLE_FLAGS and filter our flags consistantly across arches, or should we be as narrow as possible and only do -fno-stack-check for arm?  BTW, while we're at it, we should get -fstack-protector-strong in there since that appeared with gcc-4.9.

Anthony G. Basile, Ph. D.
Chair of Information Technology
D'Youville College
Buffalo, NY 14201
(716) 829-8197

More information about the uClibc mailing list