From patchwork Sun Feb 28 16:41:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nix X-Patchwork-Id: 11135 Received: (qmail 88631 invoked by alias); 28 Feb 2016 16:42:30 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 87705 invoked by uid 89); 28 Feb 2016 16:42:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.5 required=5.0 tests=AWL, BAYES_50, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=353, UD:7.0.198.g6dd47b6, UD:2.7.0.198.g6dd47b6, sk:2.7.0.1 X-HELO: mail.esperi.org.uk From: Nix To: libc-alpha@sourceware.org Subject: [PATCH 15/16] Avoid stack-protecting certain functions called from assembly. Date: Sun, 28 Feb 2016 16:41:34 +0000 Message-Id: <1456677695-29778-16-git-send-email-nix@esperi.org.uk> In-Reply-To: <1456677695-29778-1-git-send-email-nix@esperi.org.uk> References: <1456677695-29778-1-git-send-email-nix@esperi.org.uk> X-DCC-URT-Metrics: spindle 1060; Body=1 Fuz1=1 Fuz2=1 From: Nick Alcock 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). v4: Use inhibit_stack_protector. --- nptl/pthread_mutex_lock.c | 2 +- nptl/pthread_mutex_unlock.c | 2 +- setjmp/Makefile | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c index bdfa529..87a1935 100644 --- a/nptl/pthread_mutex_lock.c +++ b/nptl/pthread_mutex_lock.c @@ -520,7 +520,7 @@ hidden_def (__pthread_mutex_lock) #ifdef NO_INCR void -internal_function +internal_function inhibit_stack_protector __pthread_mutex_cond_lock_adjust (pthread_mutex_t *mutex) { assert ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0); diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c index 334ce38..5f23af1 100644 --- a/nptl/pthread_mutex_unlock.c +++ b/nptl/pthread_mutex_unlock.c @@ -33,7 +33,7 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr) __attribute_noinline__; int -internal_function attribute_hidden +internal_function inhibit_stack_protector attribute_hidden __pthread_mutex_unlock_usercnt (pthread_mutex_t *mutex, int decr) { int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); 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)