From patchwork Fri Jun 9 15:39:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 20885 Received: (qmail 94799 invoked by alias); 9 Jun 2017 15:39:50 -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 94788 invoked by uid 89); 9 Jun 2017 15:39:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-qt0-f178.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=M6JZi1bTlBsPUCmUyitPSfE45gk/Q8U7zQAR4gULfic=; b=KXIqntPI85NAK+lBPTLuRlqTOHpmnF/iqRNgUKpf1shJgKihKymQ7xvASe5nBoA1FT Q9ij1pveoeW6tUryUSWwu7msiohGGwOU0NbzYLtArmHPbxnJJt3GTATHaXsX4jNmwoq7 wyIRhywQ87PUmdr8q0gEXlmb3cIDUJlyhy+GeWYOtr30VghoqW3wcUtyGHoygIgS77wG W7RwP2R0Pf8pWOUP7IWiZXEq6RQFWuFCI7ODL4/Fykv+0hfQyp8NRcRyfEEctHY2Burg cPDVGxB84GtA7+eJYWhXlYK/n77nb3wwJbeFEgqp4A4oGcNx562vucMuKMSNAmLPXOVQ sdUQ== X-Gm-Message-State: AODbwcAI+7Zpx2obg143p4fPpfbP06JWcMyX9EecbVnOYC4VK+8P/QhR gd0pFhP9VTxsq4ZPMuueP7qLPfLAOw== X-Received: by 10.200.2.79 with SMTP id o15mr5372364qtg.26.1497022789936; Fri, 09 Jun 2017 08:39:49 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <874lvpi4p0.fsf@oldenburg.str.redhat.com> References: <451a71c6-7eb7-983d-f808-86cf50fc0dca@redhat.com> <1496876422.12598.31.camel@test-lenovo> <59390EEB.4020409@arm.com> <1496951188.15627.51.camel@test-lenovo> <593A64CC.60100@arm.com> <593A834A.7050301@arm.com> <593A84D6.40007@arm.com> <9f339124-dd5d-d677-0272-b8bba161e382@redhat.com> <593A8A26.3090800@arm.com> <593A9B29.2060103@arm.com> <593AA581.9080804@arm.com> <874lvpi4p0.fsf@oldenburg.str.redhat.com> From: "H.J. Lu" Date: Fri, 9 Jun 2017 08:39:48 -0700 Message-ID: Subject: Re: RFC: Shadow Stack support in glibc To: Florian Weimer Cc: Szabolcs Nagy , nd , Yu-cheng Yu , GNU C Library , Igor Tsimbalist , "Shanbhogue, Vedvyas" On Fri, Jun 9, 2017 at 8:03 AM, Florian Weimer wrote: > "H.J. Lu" writes: > >> We can use the unused space for SSP. > > Great. :) Something like the patch here? > Please note that SSP already stands for “stack smashing protector”, so > it's probably best not reuse the same abbreviation for another hardening > feature. SSR (Shadow Stack Register)? From 96f7b89f1850a0daa771b812eead76076525eadd Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 9 Jun 2017 08:34:44 -0700 Subject: [PATCH] x86: Add a field to jmp_buf to save shadow stack pointer Since the __saved_mask field in jmp_buf is unused for x86, replace __saved_mask with a union to save save shadow stack pointer while keeping the size of jmp_buf unchanged. * sysdeps/x86/setjmp.h: New file. --- sysdeps/x86/setjmp.h | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 sysdeps/x86/setjmp.h diff --git a/sysdeps/x86/setjmp.h b/sysdeps/x86/setjmp.h new file mode 100644 index 0000000..8d32583 --- /dev/null +++ b/sysdeps/x86/setjmp.h @@ -0,0 +1,112 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* + * ISO C99 Standard: 7.13 Nonlocal jumps + */ + +#ifndef _SETJMP_H +#define _SETJMP_H 1 + +#include + +__BEGIN_DECLS + +#include /* Get uintptr_t. */ +#include /* Get `__jmp_buf'. */ +#include + +/* Calling environment, plus possibly a saved signal mask. */ +struct __jmp_buf_tag + { + /* NOTE: The machine-dependent definitions of `__sigsetjmp' + assume that a `jmp_buf' begins with a `__jmp_buf' and that + `__mask_was_saved' follows it. Do not move these members + or add others before it. */ + __jmp_buf __jmpbuf; /* Calling environment. */ + int __mask_was_saved; /* Saved the signal mask? */ + union + { + /* Saved shadow stack pointer. */ + uintptr_t __saved_shadow_stack_pointer; + /* Saved signal mask. */ + __sigset_t __saved_mask; + } u; + }; + + +typedef struct __jmp_buf_tag jmp_buf[1]; + +/* Store the calling environment in ENV, also saving the signal mask. + Return 0. */ +extern int setjmp (jmp_buf __env) __THROWNL; + +/* Store the calling environment in ENV, also saving the + signal mask if SAVEMASK is nonzero. Return 0. + This is the internal name for `sigsetjmp'. */ +extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) __THROWNL; + +/* Store the calling environment in ENV, not saving the signal mask. + Return 0. */ +extern int _setjmp (struct __jmp_buf_tag __env[1]) __THROWNL; + +/* Do not save the signal mask. This is equivalent to the `_setjmp' + BSD function. */ +#define setjmp(env) _setjmp (env) + + +/* Jump to the environment saved in ENV, making the + `setjmp' call there return VAL, or 1 if VAL is 0. */ +extern void longjmp (struct __jmp_buf_tag __env[1], int __val) + __THROWNL __attribute__ ((__noreturn__)); + +#if defined __USE_MISC || defined __USE_XOPEN +/* Same. Usually `_longjmp' is used with `_setjmp', which does not save + the signal mask. But it is how ENV was saved that determines whether + `longjmp' restores the mask; `_longjmp' is just an alias. */ +extern void _longjmp (struct __jmp_buf_tag __env[1], int __val) + __THROWNL __attribute__ ((__noreturn__)); +#endif + + +#ifdef __USE_POSIX +/* Use the same type for `jmp_buf' and `sigjmp_buf'. + The `__mask_was_saved' flag determines whether + or not `longjmp' will restore the signal mask. */ +typedef struct __jmp_buf_tag sigjmp_buf[1]; + +/* Store the calling environment in ENV, also saving the + signal mask if SAVEMASK is nonzero. Return 0. */ +# define sigsetjmp(env, savemask) __sigsetjmp (env, savemask) + +/* Jump to the environment saved in ENV, making the + sigsetjmp call there return VAL, or 1 if VAL is 0. + Restore the signal mask if that sigsetjmp call saved it. + This is just an alias `longjmp'. */ +extern void siglongjmp (sigjmp_buf __env, int __val) + __THROWNL __attribute__ ((__noreturn__)); +#endif /* Use POSIX. */ + + +/* Define helper functions to catch unsafe code. */ +#if __USE_FORTIFY_LEVEL > 0 +# include +#endif + +__END_DECLS + +#endif /* setjmp.h */ -- 2.9.4