Lintian warning: shlib-with-executable-stack

Lintian gives these warnings on the plash deb:

W: plash: shlib-with-executable-stack usr/lib/plash/lib/libutil.so.1
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libnss_dns.so.2
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libmemusage.so
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libnsl.so.1
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libcrypt.so.1
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libnss_files.so.2
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libpcprofile.so
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libnss_nis.so.2
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libpthread.so.0
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libnss_nisplus.so.2
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libBrokenLocale.so.1
W: plash: shlib-with-executable-stack usr/lib/plash/lib/librt.so.1
W: plash: shlib-with-executable-stack var/lib/plash-chroot-jail/special/ld-linux.so.2
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libSegFault.so
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libdl.so.2
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libm.so.6
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libresolv.so.2
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libnss_hesiod.so.2
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libanl.so.1
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libnss_compat.so.2
W: plash: shlib-with-executable-stack usr/lib/plash/lib/libc.so.6

This occurs on all Ubuntu and Debian builds based on Story6, both i386 and amd64. I think it occurred before Story6 too.

We can determine whether object files or shared objects are marked as needing an executable stack using objdump. Here, "rwx" indicates the problem:

$ objdump -x glibc-build/libc.so.6
...
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rwx
...

This one is OK:

$ objdump -x glibc-build/plash/libc-misc.os
...
 15 .note.GNU-stack 00000000  0000000000000000  0000000000000000  00005aff  2**0
                  CONTENTS, READONLY
...

A more convenient tool is scanelf from the pax-utils package. scanelf -qeR glibc-build lists problematic object files. The commonality between these files seems to be that they are generated from assembler. I found scanelf was described in some Gentoo docs, The GNU Stack Quickstart. It says "So, the most common source of executable stacks in ELF binaries are packages which include raw assembly code. Note that we're not talking about inline assembly code, but rather files like .S which are written in pure assembler."

Passing --noexecstack to the assembler overrides the assembler's default. glibc was changed in 2003 to pass this option: PATCH: Use -Wa,--noexecstack for glibc .S files.

However, it looks like glibc's configure check is failing. From config.log:

configure:6246: checking whether --noexecstack is desirable for .S files
configure:6256: gcc-4.1 -fno-stack-protector -pipe -fstrict-aliasing -g1 -O3
                     -S -o conftest.s conftest.c 1>&5
configure:6259: $? = 0
configure:6264: gcc-4.1 -fno-stack-protector -pipe -fstrict-aliasing -g1 -O3  -Wa,--noexecstack
                       -c -o conftest.o conftest.s 1>&5
conftest.s: Assembler messages:
conftest.s:71: Error: file number 1 already allocated
configure:6267: $? = 1
configure:6276: result: no
...
ASFLAGS_config=''

whereas the config.log from an older non-Plash build of glibc contains:

configure:5621: checking whether --noexecstack is desirable for .S files
configure:5631: gcc-4.0 -g -O2 -isystem /home/mrs-big/sw/libc/new/glibc-2.3.5.orig/debian/include
                     -S -o conftest.s conftest.c 1>&5
configure:5634: $? = 0
configure:5639: gcc-4.0 -g -O2 -isystem /home/mrs-big/sw/libc/new/glibc-2.3.5.orig/debian/include -Wa,--noexecstack
                       -c -o conftest.o conftest.s 1>&5
configure:5642: $? = 0
configure:5651: result: yes
...
ASFLAGS_config=' -Wa,--noexecstack'

glibc is just doing a feature check for --noexecstack, but the assembler is failing with an unrelated error, Error: file number 1 already allocated. This appears to be an assembler bug, which the Linux kernel has had to work around for powerpc: Roland McGrath: PATCH: powerfc fix for assembler -g (the rest of the thread is here).

The error seems to be caused by lines like this in the assembler input:

        .file 1 "conftest.c"

Changing build-glibc-integrated.sh to use -g0 or just -g instead of -g1 in CFLAGS seems to fix the problem. Omitting any kind of -g option also works.

Here is a minimal test case to reproduce this problem in gcc:

echo "void foo(void) { }" >test.c
gcc -g1 -S test.c
gcc -g1 -c test.s

Relevant bugs: GCC bug 31872: Duplicate file numbers for .file directive with -g3 -O0

Why did I use -g1? It was used by Debian's packaging. This commit introduced it. This large commit changed it to -g.

The documentation for the -g option says "Level 1 produces minimal information, enough for making backtraces in parts of the program that you don't plan to debug. This includes descriptions of functions and external variables, but no information about local variables and no line numbers."

Filed GCC bug #35925

Filed glibc bug #6428

Resolution

Applied patch from glibc bug.

PlashIssues/LintianExecutableStack (last edited 2008-04-23 21:13:26 by MarkSeaborn)