Patchwork [13/14] Avoid stack-protecting certain functions called from assembly.

login
register
mail settings
Submitter Nix
Date Feb. 24, 2016, 11:28 p.m.
Message ID <1456356500-25601-14-git-send-email-nix@esperi.org.uk>
Download mbox | patch
Permalink /patch/11061/
State New
Headers show

Comments

Nix - Feb. 24, 2016, 11:28 p.m.
From: Nick Alcock <nick.alcock@oracle.com>

This is the problematic part.  Without -fno-stack-protector on
__pthread_mutex_cond_lock_adjust() and __pthread_mutex_unlock_usercnt(),
nptl/tst-cond24 and nptl/tst-cond25 receive a NULL mutex at unlock time
and segfault.  However... I don't understand why.  It is the callee's
responsibility both to add the stack canary and to initialize it, just
like any other local variable.  It has to be, or the ABI for stack-
protected code would be incompatible with that for non-protected code.
But the fact remains that
sysdeps/unix/sysv/linux/i386/pthread_cond_timedwait.S both explicitly
mentions the stack frame layout and calls this function, and this call
goes wrong if we stack-protect it.

So this is somewhere where I need someone to tell me what's special about
sysdeps/unix/sysv/linux/i386/pthread_cond_timedwait.S (and in particular
special about priority-inheritance mutexes: everything else works),
before I can be confident that this is even remotely the right thing to
do.

We also de-stack-protect setjmp/sigjmp.c: it receives a sibcall from
sysdeps/x86_64/setjmp.S and lands in rtld, but is *not* rebuilt by
the machinery that rebuilds almost everything else that lands in
rtld with an appropriate MODULE_NAME.

Similar fixups may be required for things called directly from
assembly on other architectures.

v2: de-stack-protect setjmp/sigjmp.c.
v3: Use $(no-stack-protector).
---
 nptl/Makefile   | 4 ++++
 setjmp/Makefile | 4 ++++
 2 files changed, 8 insertions(+)

Patch

diff --git a/nptl/Makefile b/nptl/Makefile
index b2b3768..d08009e 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -329,6 +329,10 @@  endif
 
 # Parts of nptl-init.c are called before the stack guard is initialized.
 CFLAGS-nptl-init.c += $(no-stack-protector)
+# Parts of these files are called from assembler, with a hand-made stack,
+# sans canary.
+CFLAGS-pthread_mutex_cond_lock.c += $(no-stack-protector)
+CFLAGS-pthread_mutex_unlock.c += $(no-stack-protector)
 
 modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
 		tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
diff --git a/setjmp/Makefile b/setjmp/Makefile
index 5b677cc..b617a84 100644
--- a/setjmp/Makefile
+++ b/setjmp/Makefile
@@ -35,3 +35,7 @@  tests-static	:= tst-setjmp-static
 include ../Rules
 
 $(objpfx)tst-setjmp-fp: $(libm)
+
+# This is sibcalled directly from arch-specific assembly, included in rtld,
+# but never rebuilt, so it must never be built with stack protection.
+CFLAGS-sigjmp.c += $(no-stack-protector)