From patchwork Tue Jul 24 13:24:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 28586 Received: (qmail 115116 invoked by alias); 24 Jul 2018 13:24:44 -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 114794 invoked by uid 89); 24 Jul 2018 13:24:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.8 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-pl0-f66.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=FH+NtHmV5OEFDHdx/RaWFj3FPkyvKzZrsHV7175BUPI=; b=JoWd1Xpy9QKQ/NUN2oGAlzfcjwT3yRzGeeM9vMkcc6ITrDAvQewF+88VnS+KjScScD LHRAHETsjaAzJO49zlJjNP54MIcaDfQlz9aZSTR+ZsWSvMX3YLy9Jgpa6F5mNoofbJiH d5Pkt8XWoRo7Sy/dqwOSEogguUfZZr5Kbej1nsn7pW859zx1BbVHflfnWCFplTmaYLOs oGCOfFRaSJNWsL28mHBrdm7lKsZgUIzTlhc60LufDVWKp2zono574dJI2oPhaascXOtF EUIeJ+NeDjPNrJUaQa/9LudXwDEGSL1V1lwx+qguo1xhkRhZKYcrBbK78bmsTDnRlLHd hyRw== Return-Path: Date: Tue, 24 Jul 2018 06:24:11 -0700 From: "H.J. Lu" To: Carlos O'Donell Cc: libc-alpha@sourceware.org Subject: V2 [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control Message-ID: <20180724132411.GA17974@gmail.com> References: <20180721142035.21059-1-hjl.tools@gmail.com> <20180721142035.21059-5-hjl.tools@gmail.com> <6b2d54fa-28bc-434c-d7ae-405218ac00d4@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <6b2d54fa-28bc-434c-d7ae-405218ac00d4@redhat.com> User-Agent: Mutt/1.10.0 (2018-05-17) On Mon, Jul 23, 2018 at 11:05:15PM -0400, Carlos O'Donell wrote: > On 07/21/2018 10:20 AM, H.J. Lu wrote: > > /* CET features: > > IBT: GNU_PROPERTY_X86_FEATURE_1_IBT > > SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK > > */ > > > > /* Return CET features in unsigned long long *addr: > > features: addr[0]. > > shadow stack base address: addr[1]. > > shadow stack size: addr[2]. > > */ > > # define ARCH_CET_STATUS 0x3001 > > /* Disable CET features in unsigned int features. */ > > # define ARCH_CET_DISABLE 0x3002 > > /* Lock all CET features. */ > > # define ARCH_CET_LOCK 0x3003 > > /* Allocate a new shadow stack with unsigned long long *addr: > > IN: requested shadow stack size: *addr. > > OUT: allocated shadow stack address: *addr. > > */ > > # define ARCH_CET_ALLOC_SHSTK 0x3004 > > /* Return legacy region bitmap info in unsigned long long *addr: > > address: addr[0]. > > size: addr[1]. > > */ > > # define ARCH_CET_LEGACY_BITMAP 0x3005 > > > > * sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add > > bits/prctl.h. > > * sysdeps/unix/sysv/linux/bits/prctl.h: New file. > > * sysdeps/unix/sysv/linux/x86/bits/prctl.h: Likewise. > > * sysdeps/unix/sysv/linux/sys/prctl.h: Include . > > * sysdeps/unix/sysv/linux/x86/cpu-features.c: Include > > . > > (get_cet_status): Call arch_prctl with ARCH_CET_STATUS. > > * sysdeps/unix/sysv/linux/x86/dl-cet.h: Include . > > (dl_cet_allocate_legacy_bitmap): Call arch_prctl with > > ARCH_CET_LEGACY_BITMAP. > > (dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE. > > (dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK. > > * sysdeps/x86/libc-start.c: Include . > > --- > > The prctl.h values don't appear in any published kernel. > > What's the status for these? The CET kernel changes have been submitted and under discussion. We believe that this is the final CET kernel interface. > > We can't ship them in the public prctl.h header unless they are already > in a public kernel or committed and basically ready to go out in a public > kernel. > > You could rework this to only use the values internally and that would > be OK, since no user needs these yet, we are the primary CET user for > now. > Like this? H.J. Reviewed-by: Carlos O'Donell --- /* CET features: IBT: GNU_PROPERTY_X86_FEATURE_1_IBT SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK */ /* Return CET features in unsigned long long *addr: features: addr[0]. shadow stack base address: addr[1]. shadow stack size: addr[2]. */ # define ARCH_CET_STATUS 0x3001 /* Disable CET features in unsigned int features. */ # define ARCH_CET_DISABLE 0x3002 /* Lock all CET features. */ # define ARCH_CET_LOCK 0x3003 /* Allocate a new shadow stack with unsigned long long *addr: IN: requested shadow stack size: *addr. OUT: allocated shadow stack address: *addr. */ # define ARCH_CET_ALLOC_SHSTK 0x3004 /* Return legacy region bitmap info in unsigned long long *addr: address: addr[0]. size: addr[1]. */ # define ARCH_CET_LEGACY_BITMAP 0x3005 Note: sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h should be renamed to sysdeps/unix/sysv/linux/x86/bits/prctl.h after the CET kernel interface has been committed into the public kernel. * sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add bits/prctl.h. * sysdeps/unix/sysv/linux/bits/prctl.h: New file. * sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h: Likewise. * sysdeps/unix/sysv/linux/sys/prctl.h: Include . * sysdeps/unix/sysv/linux/x86/cpu-features.c: Include and . (get_cet_status): Call arch_prctl with ARCH_CET_STATUS. * sysdeps/unix/sysv/linux/x86/dl-cet.h: Include and . (dl_cet_allocate_legacy_bitmap): Call arch_prctl with ARCH_CET_LEGACY_BITMAP. (dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE. (dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK. * sysdeps/x86/libc-start.c: Include . --- sysdeps/unix/sysv/linux/Makefile | 3 +- sysdeps/unix/sysv/linux/bits/prctl.h | 21 ++++++++ sysdeps/unix/sysv/linux/sys/prctl.h | 1 + .../unix/sysv/linux/x86/bits/prctl-internal.h | 52 +++++++++++++++++++ sysdeps/unix/sysv/linux/x86/cpu-features.c | 10 ++++ sysdeps/unix/sysv/linux/x86/dl-cet.h | 32 +++++++++--- sysdeps/x86/libc-start.c | 3 ++ 7 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/bits/prctl.h create mode 100644 sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index f71cc39c7e..0bcc5287d9 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -40,7 +40,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ bits/signalfd.h bits/timerfd.h bits/epoll.h \ bits/socket_type.h bits/syscall.h bits/sysctl.h \ bits/mman-linux.h bits/mman-shared.h bits/ptrace-shared.h \ - bits/siginfo-arch.h bits/siginfo-consts-arch.h + bits/siginfo-arch.h bits/siginfo-consts-arch.h \ + bits/prctl.h tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ diff --git a/sysdeps/unix/sysv/linux/bits/prctl.h b/sysdeps/unix/sysv/linux/bits/prctl.h new file mode 100644 index 0000000000..be96218066 --- /dev/null +++ b/sysdeps/unix/sysv/linux/bits/prctl.h @@ -0,0 +1,21 @@ +/* Copyright (C) 2018 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 + . */ + +#ifndef _BITS_PRCTL_H +#define _BITS_PRCTL_H 1 + +#endif /* bits/prctl.h */ diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h index 683d16748f..6c4f643c75 100644 --- a/sysdeps/unix/sysv/linux/sys/prctl.h +++ b/sysdeps/unix/sysv/linux/sys/prctl.h @@ -20,6 +20,7 @@ #include #include /* The magic values come from here */ +#include __BEGIN_DECLS diff --git a/sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h b/sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h new file mode 100644 index 0000000000..08408d5b88 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h @@ -0,0 +1,52 @@ +/* FIXME: Rename this file to prctl.h after the CET kernel interface + has been committed into the public kernel. */ +#undef _BITS_PRCTL_H + +/* Copyright (C) 2018 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 + . */ + +#ifndef _BITS_PRCTL_H +#define _BITS_PRCTL_H 1 + +#ifndef ARCH_CET_STATUS +/* CET features: + IBT: GNU_PROPERTY_X86_FEATURE_1_IBT + SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK + */ +/* Return CET features in unsigned long long *addr: + features: addr[0]. + shadow stack base address: addr[1]. + shadow stack size: addr[2]. + */ +# define ARCH_CET_STATUS 0x3001 +/* Disable CET features in unsigned int features. */ +# define ARCH_CET_DISABLE 0x3002 +/* Lock all CET features. */ +# define ARCH_CET_LOCK 0x3003 +/* Allocate a new shadow stack with unsigned long long *addr: + IN: requested shadow stack size: *addr. + OUT: allocated shadow stack address: *addr. + */ +# define ARCH_CET_ALLOC_SHSTK 0x3004 +/* Return legacy region bitmap info in unsigned long long *addr: + address: addr[0]. + size: addr[1]. + */ +# define ARCH_CET_LEGACY_BITMAP 0x3005 +#endif /* ARCH_CET_STATUS */ + +#endif /* bits/prctl.h */ diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c index 7c9df9b794..c042783ae9 100644 --- a/sysdeps/unix/sysv/linux/x86/cpu-features.c +++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c @@ -17,9 +17,19 @@ . */ #if CET_ENABLED +# include +/* FIXME: Remove this after has been renamed to + . */ +# include + static inline int __attribute__ ((always_inline)) get_cet_status (void) { + unsigned long long cet_status[3]; + INTERNAL_SYSCALL_DECL (err); + if (INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_STATUS, + cet_status) == 0) + return cet_status[0]; return 0; } diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h index ae81e2f2ca..edf8cd7394 100644 --- a/sysdeps/unix/sysv/linux/x86/dl-cet.h +++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h @@ -15,23 +15,43 @@ License along with the GNU C Library; if not, see . */ +#include +/* FIXME: Remove this after has been renamed to + . */ +#include + static inline int __attribute__ ((always_inline)) dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap) { - /* FIXME: Need syscall support. */ - return -1; + /* Allocate legacy bitmap. */ + INTERNAL_SYSCALL_DECL (err); +#ifdef __LP64__ + return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, + ARCH_CET_LEGACY_BITMAP, legacy_bitmap); +#else + unsigned long long legacy_bitmap_u64[2]; + int res = INTERNAL_SYSCALL (arch_prctl, err, 2, + ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64); + if (res == 0) + { + legacy_bitmap[0] = legacy_bitmap_u64[0]; + legacy_bitmap[1] = legacy_bitmap_u64[1]; + } + return res; +#endif } static inline int __attribute__ ((always_inline)) dl_cet_disable_cet (unsigned int cet_feature) { - /* FIXME: Need syscall support. */ - return -1; + INTERNAL_SYSCALL_DECL (err); + return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_DISABLE, + cet_feature); } static inline int __attribute__ ((always_inline)) dl_cet_lock_cet (void) { - /* FIXME: Need syscall support. */ - return -1; + INTERNAL_SYSCALL_DECL (err); + return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_LOCK, 0); } diff --git a/sysdeps/x86/libc-start.c b/sysdeps/x86/libc-start.c index 43aba9d061..eb5335c154 100644 --- a/sysdeps/x86/libc-start.c +++ b/sysdeps/x86/libc-start.c @@ -16,6 +16,9 @@ . */ #ifndef SHARED +/* Define I386_USE_SYSENTER to support syscall during startup in static + PIE. */ +# include # include # include # include