From patchwork Tue Jun 10 15:13:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Khrustalev X-Patchwork-Id: 114149 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CD807382D2B2 for ; Tue, 10 Jun 2025 15:14:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CD807382D2B2 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 9A5F8385783C for ; Tue, 10 Jun 2025 15:13:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9A5F8385783C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9A5F8385783C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568415; cv=none; b=Q0x+5AkekK6mX4PMbFTBrdseLjxVlfgDht7Dj70xT1jlFNuKZBSnxsRiotaWpvR/k2djgIPy0oFImMBd4RmEo1a/LYj5+5fWM386TM/nJj9iUYwLuhqVDgk9lTgcV0CKqkoKLs5d7cRIVe1LLxFnRqHkYIIxYAy9V4cwN8xLu3w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568415; c=relaxed/simple; bh=RopSxOstancsIpzjma81GosZIquK5yZiW3l0MhQpHac=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=j/a//3hE0BYOdI96L3HO0tcFYptjBMgKMXg1o4mN13hpgHlEfHMeQdI2Rprnb12ht387HkQNFFtAmTma4cfybbsT51h9seH6Xyb9Yf+Hn4IWC2/GvagASdNvyhAYUyPFOxYKyUo9c3mwL2VJDsBan14qGcODmJRNYruuPYfQ7Cs= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9A5F8385783C Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0BC64169C; Tue, 10 Jun 2025 08:13:16 -0700 (PDT) Received: from udebian.localdomain (unknown [10.1.37.41]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 07BFF3F59E; Tue, 10 Jun 2025 08:13:33 -0700 (PDT) From: Yury Khrustalev To: libc-alpha@sourceware.org Cc: Rick Edgecombe , Mark Brown , Deepak Gupta , Adhemerval Zanella Netto , Wilco Dijkstra , Carlos O'Donell , Florian Weimer , Szabolcs Nagy Subject: [RFC 1/5] aarch64: GCS: use internal struct in __alloc_gcs Date: Tue, 10 Jun 2025 16:13:16 +0100 Message-Id: <20250610151320.885131-2-yury.khrustalev@arm.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250610151320.885131-1-yury.khrustalev@arm.com> References: <20250610151320.885131-1-yury.khrustalev@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org This will simplify using this function for allocating shadow stacks. --- sysdeps/aarch64/__alloc_gcs.c | 15 +++++++++++---- sysdeps/aarch64/aarch64-gcs.h | 17 ++++++++++++++++- sysdeps/unix/sysv/linux/aarch64/makecontext.c | 4 +--- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/sysdeps/aarch64/__alloc_gcs.c b/sysdeps/aarch64/__alloc_gcs.c index e70b4594a2..b98e5fcdba 100644 --- a/sysdeps/aarch64/__alloc_gcs.c +++ b/sysdeps/aarch64/__alloc_gcs.c @@ -15,6 +15,8 @@ License along with the GNU C Library; if not, see . */ +#include "aarch64-gcs.h" + #include #include #include @@ -34,7 +36,7 @@ map_shadow_stack (void *addr, size_t size, unsigned long flags) #define GCS_ALTSTACK_RESERVE 160 void * -__alloc_gcs (size_t stack_size, void **ss_base, size_t *ss_size) +__alloc_gcs (size_t stack_size, struct gcs_record *gcs) { size_t size = (stack_size / 2 + GCS_ALTSTACK_RESERVE) & -8UL; if (size > GCS_MAX_SIZE) @@ -45,9 +47,6 @@ __alloc_gcs (size_t stack_size, void **ss_base, size_t *ss_size) if (base == MAP_FAILED) return NULL; - *ss_base = base; - *ss_size = size; - uint64_t *gcsp = (uint64_t *) ((char *) base + size); /* Skip end of GCS token. */ gcsp--; @@ -58,6 +57,14 @@ __alloc_gcs (size_t stack_size, void **ss_base, size_t *ss_size) __munmap (base, size); return NULL; } + + if (gcs != NULL) + { + gcs->gcs_base = base; + gcs->gcs_token = gcsp; + gcs->gcs_size = size; + } + /* Return the target GCS pointer for context switch. */ return gcsp + 1; } diff --git a/sysdeps/aarch64/aarch64-gcs.h b/sysdeps/aarch64/aarch64-gcs.h index 162ef18726..8e253ed32f 100644 --- a/sysdeps/aarch64/aarch64-gcs.h +++ b/sysdeps/aarch64/aarch64-gcs.h @@ -23,6 +23,21 @@ #include #include -void *__alloc_gcs (size_t, void **, size_t *) attribute_hidden; +struct gcs_record +{ + void *gcs_base; + void *gcs_token; + size_t gcs_size; +}; + +void *__alloc_gcs (size_t, struct gcs_record *) attribute_hidden; + +static inline bool +has_gcs (void) +{ + register unsigned long x16 asm ("x16") = 1; + asm ("hint 40" /* chkfeat x16 */ : "+r" (x16)); + return x16 == 0; +} #endif diff --git a/sysdeps/unix/sysv/linux/aarch64/makecontext.c b/sysdeps/unix/sysv/linux/aarch64/makecontext.c index a2eab9efc6..4485723cfb 100644 --- a/sysdeps/unix/sysv/linux/aarch64/makecontext.c +++ b/sysdeps/unix/sysv/linux/aarch64/makecontext.c @@ -36,9 +36,7 @@ static struct _aarch64_ctx *extension (void *p) static void * alloc_makecontext_gcs (size_t stack_size) { - void *base; - size_t size; - void *gcsp = __alloc_gcs (stack_size, &base, &size); + void *gcsp = __alloc_gcs (stack_size, NULL); if (gcsp == NULL) /* ENOSYS, bad size or OOM. */ abort (); From patchwork Tue Jun 10 15:13:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Khrustalev X-Patchwork-Id: 114150 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 308A5382C0B5 for ; Tue, 10 Jun 2025 15:14:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 308A5382C0B5 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 352F93857032 for ; Tue, 10 Jun 2025 15:13:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 352F93857032 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 352F93857032 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568417; cv=none; b=d12YByeyvYT8V95d0ZXxEqyEXcYfMrZIUW2WLGkCcAjwJ43dJt3/yiugik+xI7cCYd1jUptGVcV1cpqs2HqUo2swVUC5DFgSBmKjyuyXJHDMvpZ5Q2ppGYRP+BmcuxP1xfPTUh8uhFmlaDxH3Z9nOfmsvV1Z/tNPvyRB5lrNxsQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568417; c=relaxed/simple; bh=lJu6HOPs+SfPVqizfaYA198YnnG1N+T6cUWWHzSbQv4=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=KxgNF1e6qt8+bjU1IKYRgCws4rd4zHZ1uHau9y5Zv1olVQrRL7xt/rbiDDi3ktYhEOI6hD+NJkpWUsofDlXpASdyLM5KcTCrcRlfeVCep8sILJdMqOPAYQtQ0SXrh83stBHFmw7KlP/4YeLCkyh5eaxEuRwRRRzY9Ix+9sllRpk= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 352F93857032 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9B59A16F8; Tue, 10 Jun 2025 08:13:17 -0700 (PDT) Received: from udebian.localdomain (unknown [10.1.37.41]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9603B3F59E; Tue, 10 Jun 2025 08:13:35 -0700 (PDT) From: Yury Khrustalev To: libc-alpha@sourceware.org Cc: Rick Edgecombe , Mark Brown , Deepak Gupta , Adhemerval Zanella Netto , Wilco Dijkstra , Carlos O'Donell , Florian Weimer , Szabolcs Nagy Subject: [RFC 2/5] aarch64: check if clone3 supports shadow stack Date: Tue, 10 Jun 2025 16:13:17 +0100 Message-Id: <20250610151320.885131-3-yury.khrustalev@arm.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250610151320.885131-1-yury.khrustalev@arm.com> References: <20250610151320.885131-1-yury.khrustalev@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Rely on the version of the currently running kernel and use existing mechanism to determine this version (same that was used for checks related to SVE). Since we only need this information in certain case, we try to guard this additional code with macros and extra flag. --- sysdeps/aarch64/cpu-features.h | 1 + .../unix/sysv/linux/aarch64/cpu-features.c | 96 ++++++++++++++----- 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h index ef4e947e8c..2dfda6f8f1 100644 --- a/sysdeps/aarch64/cpu-features.h +++ b/sysdeps/aarch64/cpu-features.h @@ -64,6 +64,7 @@ struct cpu_features bool sve; bool prefer_sve_ifuncs; bool mops; + bool clone3_has_shadow_stack; }; #endif /* _CPU_FEATURES_AARCH64_H */ diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c index 6d63c8a9ec..33bb2d1f66 100644 --- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c +++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c @@ -63,19 +63,13 @@ get_midr_from_mcpu (const struct tunable_str_t *mcpu) return UINT64_MAX; } -#if __LINUX_KERNEL_VERSION < 0x060200 - -/* Return true if we prefer using SVE in string ifuncs. Old kernels disable - SVE after every system call which results in unnecessary traps if memcpy - uses SVE. This is true for kernels between 4.15.0 and before 6.2.0, except - for 5.14.0 which was patched. For these versions return false to avoid using - SVE ifuncs. - Parse the kernel version into a 24-bit kernel.major.minor value without - calling any library functions. If uname() is not supported or if the version - format is not recognized, assume the kernel is modern and return true. */ +/* Parse the kernel version into a 24-bit kernel.major.minor value without + calling any library functions. If uname() is not supported or if the + version format is not recognized, return 0 which indicates unknown + version. */ -static inline bool -prefer_sve_ifuncs (void) +static inline unsigned int +get_current_kernel_version (void) { struct utsname buf; const char *p = &buf.release[0]; @@ -83,7 +77,7 @@ prefer_sve_ifuncs (void) int val; if (__uname (&buf) < 0) - return true; + return 0; for (int shift = 16; shift >= 0; shift -= 8) { @@ -94,6 +88,25 @@ prefer_sve_ifuncs (void) break; } + return kernel; +} + +#if __LINUX_KERNEL_VERSION < 0x060200 + +/* Return true if we prefer using SVE in string ifuncs. Old kernels disable + SVE after every system call which results in unnecessary traps if memcpy + uses SVE. This is true for kernels between 4.15.0 and before 6.2.0, except + for 5.14.0 which was patched. For these versions return false to avoid using + SVE ifuncs. + + If kernel version is unknown, assume the kernel is modern and return true. */ + +static inline bool +prefer_sve_ifuncs (int kernel) +{ + if (kernel == 0x0) + /* Unknown version. */ + return true; if (kernel >= 0x060200 || kernel == 0x050e00) return true; if (kernel >= 0x040f00) @@ -103,6 +116,23 @@ prefer_sve_ifuncs (void) #endif +#if __LINUX_KERNEL_VERSION < 0x061000 + +/* Kernel supports shadow stacks for threads allocated by userspace since + 6.16 TBD. Starting with this version we can use shadow_stack_token in + struct clone_args. */ + +static inline bool +clone3_has_shadow_stack (int kernel) +{ + if (kernel >= 0x061000) + return true; + return false; +} + +#endif + + static inline void init_cpu_features (struct cpu_features *cpu_features) { @@ -164,20 +194,40 @@ init_cpu_features (struct cpu_features *cpu_features) 0, 0, 0); #endif - /* Check if SVE is supported. */ - cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE; + /* Check if MOPS is supported. */ + cpu_features->mops = GLRO (dl_hwcap2) & HWCAP2_MOPS; - cpu_features->prefer_sve_ifuncs = cpu_features->sve; + uint64_t hwcap = GLRO (dl_hwcap); + + /* We only need to determine current kernel version in a few + cases. */ +#if __LINUX_KERNEL_VERSION < 0x060200 \ + || __LINUX_KERNEL_VERSION < 0x061000 + bool need_kernel_ver = hwcap & (HWCAP_SVE | HWCAP_GCS); + unsigned int kernel __attribute__ ((unused)); + kernel = need_kernel_ver ? get_current_kernel_version () : 0; +#endif + /* Check if SVE is supported. */ + cpu_features->sve = hwcap & HWCAP_SVE; + cpu_features->prefer_sve_ifuncs = cpu_features->sve; #if __LINUX_KERNEL_VERSION < 0x060200 if (cpu_features->sve) - cpu_features->prefer_sve_ifuncs = prefer_sve_ifuncs (); + cpu_features->prefer_sve_ifuncs = prefer_sve_ifuncs (kernel); #endif - /* Check if MOPS is supported. */ - cpu_features->mops = GLRO (dl_hwcap2) & HWCAP2_MOPS; - - if (GLRO (dl_hwcap) & HWCAP_GCS) - /* GCS status may be updated later by binary compatibility checks. */ - GL (dl_aarch64_gcs) = TUNABLE_GET (glibc, cpu, aarch64_gcs, uint64_t, 0); + /* Check if GCS is supported. */ + if (hwcap & HWCAP_GCS) + { + cpu_features->clone3_has_shadow_stack = true; +#if __LINUX_KERNEL_VERSION < 0x061000 + /* It only makes sense to check for shadow stack support if + hardware supports it. */ + cpu_features->clone3_has_shadow_stack = clone3_has_shadow_stack (kernel); +#endif + /* GCS status may be updated later by binary compatibility checks. */ + GL (dl_aarch64_gcs) = TUNABLE_GET (glibc, cpu, aarch64_gcs, uint64_t, 0); + } + else + cpu_features->clone3_has_shadow_stack = false; } From patchwork Tue Jun 10 15:13:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Khrustalev X-Patchwork-Id: 114151 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7B828382C0B7 for ; Tue, 10 Jun 2025 15:15:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7B828382C0B7 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id C9F5B385735B for ; Tue, 10 Jun 2025 15:13:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C9F5B385735B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C9F5B385735B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568418; cv=none; b=GzGAriq72c9YCtIiajdHLP9xIWwVJrE/l7zjeN62Fm2sfWBm+Y1RU6urtndiXUa4bmeCubT8+TKQEEGeeoqN6wVdo6YJNGwOkrYDYEGNfB8lNOQCexIFaMrunwdXctgc6iWfmHVZJa20lmnz2vb+BQ69lyLtTUmbgHZqRCsSFV0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568418; c=relaxed/simple; bh=JQ6ZFtiTZ4U2O/rcJT1901bnkzWoBk8kzD2ocEPE7Ig=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=DUiuSy56rETNdOI9F9lKbj74MuGNKjytlPmFykKx+c3Dg2rpq+7RtdxtnNJCE1mVmlt8r+JV4FFC0s9W1faXyxEXrw1RRBpbECCTw0cmBRJvwJznxDqOfCIJULuiwkbsB/ULQNzu0RX9abOIzyMBXJMcN5uEvk67h0pGweFS4XU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C9F5B385735B Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 346C71713; Tue, 10 Jun 2025 08:13:19 -0700 (PDT) Received: from udebian.localdomain (unknown [10.1.37.41]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2FE2A3F59E; Tue, 10 Jun 2025 08:13:37 -0700 (PDT) From: Yury Khrustalev To: libc-alpha@sourceware.org Cc: Rick Edgecombe , Mark Brown , Deepak Gupta , Adhemerval Zanella Netto , Wilco Dijkstra , Carlos O'Donell , Florian Weimer , Szabolcs Nagy Subject: [RFC 3/5] clone: Add clone_arg field for shadow stack Date: Tue, 10 Jun 2025 16:13:18 +0100 Message-Id: <20250610151320.885131-4-yury.khrustalev@arm.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250610151320.885131-1-yury.khrustalev@arm.com> References: <20250610151320.885131-1-yury.khrustalev@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org --- sysdeps/unix/sysv/linux/clone-internal.c | 7 +++++-- sysdeps/unix/sysv/linux/clone3.h | 2 ++ sysdeps/unix/sysv/linux/spawni.c | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sysdeps/unix/sysv/linux/clone-internal.c b/sysdeps/unix/sysv/linux/clone-internal.c index 9a1f27d017..a61645cad2 100644 --- a/sysdeps/unix/sysv/linux/clone-internal.c +++ b/sysdeps/unix/sysv/linux/clone-internal.c @@ -27,6 +27,7 @@ #define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */ #define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */ #define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */ +#define CLONE_ARGS_SIZE_VER3 96 /* sizeof fourth published struct */ #define sizeof_field(TYPE, MEMBER) sizeof ((((TYPE *)0)->MEMBER)) #define offsetofend(TYPE, MEMBER) \ @@ -40,8 +41,10 @@ _Static_assert (offsetofend (struct clone_args, set_tid_size) == CLONE_ARGS_SIZE "offsetofend (struct clone_args, set_tid_size) != CLONE_ARGS_SIZE_VER1"); _Static_assert (offsetofend (struct clone_args, cgroup) == CLONE_ARGS_SIZE_VER2, "offsetofend (struct clone_args, cgroup) != CLONE_ARGS_SIZE_VER2"); -_Static_assert (sizeof (struct clone_args) == CLONE_ARGS_SIZE_VER2, - "sizeof (struct clone_args) != CLONE_ARGS_SIZE_VER2"); +_Static_assert (offsetofend (struct clone_args, shadow_stack_token) == CLONE_ARGS_SIZE_VER3, + "offsetofend (struct clone_args, shadow_stack) != CLONE_ARGS_SIZE_VER3"); +_Static_assert (sizeof (struct clone_args) == CLONE_ARGS_SIZE_VER3, + "sizeof (struct clone_args) != CLONE_ARGS_SIZE_VER3"); int __clone_internal_fallback (struct clone_args *cl_args, diff --git a/sysdeps/unix/sysv/linux/clone3.h b/sysdeps/unix/sysv/linux/clone3.h index 847ca96d0d..e16a407774 100644 --- a/sysdeps/unix/sysv/linux/clone3.h +++ b/sysdeps/unix/sysv/linux/clone3.h @@ -61,6 +61,8 @@ struct clone_args __aligned_uint64_t set_tid_size; /* File descriptor for target cgroup of child (since Linux 5.7). */ __aligned_uint64_t cgroup; + /* Shadow stack support (since Linux 6.15 TBD). */ + __aligned_uint64_t shadow_stack_token; }; #endif /* clone3.h */ diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c index eca1a84254..5f6b0dd19b 100644 --- a/sysdeps/unix/sysv/linux/spawni.c +++ b/sysdeps/unix/sysv/linux/spawni.c @@ -415,6 +415,7 @@ __spawnix (int *pid, const char *file, /* This is require for clone fallback, where pidfd is returned on parent_tid. */ .parent_tid = use_pidfd ? (uintptr_t) &args.pidfd : 0, + .shadow_stack_token = 0, }; #ifdef HAVE_CLONE3_WRAPPER args.use_clone3 = true; From patchwork Tue Jun 10 15:13:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Khrustalev X-Patchwork-Id: 114153 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 924FF3842425 for ; Tue, 10 Jun 2025 15:19:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 924FF3842425 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 659C6382D2AB for ; Tue, 10 Jun 2025 15:13:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 659C6382D2AB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 659C6382D2AB Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568420; cv=none; b=U4FQLDxW0fLGMj9GDooLn+OBhaHWN+wG+uDfB3RohMC6jX77ETG9i92WXBLSBRlCrgTF5M3Qlk836PmB2IkNBrWoR/4bIxhfpn5WlMgMzcBp3Tg7pVl0hrZuul3kWEgXyyAVb8mwvR9hfAdZwDXJqiFiRMnVGIFq/qcaeKlHU9E= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568420; c=relaxed/simple; bh=vx2zszk3yX64XMCUHg5LE0VIWbuOLpElTjjjK8zhHKw=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=wc+eLRmYYmfpjMLb6nSGf4/iEaeto8vTTs5NFlQE+XOnYBOlj5SHa4aCivZbiUrLz9JZYQGhcMVymildSIM5jNcQKVaOj0arfUe6L9O65ZFW6RK81+5d6ZaZX/Y8e65jHLGqPJZfkSA7ckx2+McbmJSMngtcY2e4pBXv2M2et0s= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 659C6382D2AB Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C38C31758; Tue, 10 Jun 2025 08:13:20 -0700 (PDT) Received: from udebian.localdomain (unknown [10.1.37.41]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BE7063F59E; Tue, 10 Jun 2025 08:13:38 -0700 (PDT) From: Yury Khrustalev To: libc-alpha@sourceware.org Cc: Rick Edgecombe , Mark Brown , Deepak Gupta , Adhemerval Zanella Netto , Wilco Dijkstra , Carlos O'Donell , Florian Weimer , Szabolcs Nagy Subject: [RFC 4/5] nptl: Add libc allocated shadow stack for new threads Date: Tue, 10 Jun 2025 16:13:19 +0100 Message-Id: <20250610151320.885131-5-yury.khrustalev@arm.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250610151320.885131-1-yury.khrustalev@arm.com> References: <20250610151320.885131-1-yury.khrustalev@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Includes aarch64 GCS support code, does not include x86 shstk support (should be similar to the aarch64 case). Uses extended clone3 interface that allows to pass pointer to architecture-defined token on shadow stack. Co-authored-by: Szabolcs Nagy --- nptl/descr.h | 7 +++++ nptl/pthread_create.c | 22 ++++++++++++++ sysdeps/aarch64/libc-shadow-stack.h | 46 +++++++++++++++++++++++++++++ sysdeps/generic/libc-shadow-stack.h | 25 ++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 sysdeps/aarch64/libc-shadow-stack.h create mode 100644 sysdeps/generic/libc-shadow-stack.h diff --git a/nptl/descr.h b/nptl/descr.h index ada6867a19..733e7b0ce6 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -384,6 +384,13 @@ struct pthread /* This is what the user specified and what we will report. */ size_t reported_guardsize; + /* Shadow stack base pointer. */ + void *shadow_stack_base; + /* Shadow stack architecture-defined token. */ + void *shadow_stack_token; + /* Shadow stack size. */ + size_t shadow_stack_size; + /* Thread Priority Protection data. */ struct priority_protection_data *tpp; diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index e1033d4ee6..7996f4e444 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -294,6 +295,9 @@ static int create_thread (struct pthread *pd, const struct pthread_attr *attr, .stack = (uintptr_t) stackaddr, .stack_size = stacksize, .tls = (uintptr_t) tp, + /* This should point to the architecture-defined token placed + * on correctly allocated shadow stack. */ + .shadow_stack_token = (uintptr_t) pd->shadow_stack_token, }; int ret = __clone_internal (&args, &start_thread, pd); if (__glibc_unlikely (ret == -1)) @@ -574,6 +578,10 @@ start_thread (void *arg) pd->setxid_futex = 0; } + /* Shadow stack information required to deallocate it later. */ + void *ss_base = pd->shadow_stack_base; + size_t ss_size = pd->shadow_stack_size; + /* If the thread is detached free the TCB. */ if (IS_DETACHED (pd)) /* Free the TCB. */ @@ -582,6 +590,11 @@ start_thread (void *arg) /* Remove the associated name from the thread stack. */ name_stack_maps (pd, false); + /* Free the shadow stack if we allocated one, no more ret + is possible after this, must be inline right before exit. */ + if (ss_base) + INTERNAL_SYSCALL_CALL (munmap, ss_base, ss_size); + out: /* We cannot call '_exit' here. '_exit' will terminate the process. @@ -713,6 +726,15 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr, pd->schedpolicy = self->schedpolicy; pd->schedparam = self->schedparam; + /* Set up a shadow stack. */ + err = THREAD_ALLOC_SHADOW_STACK (pd, stacksize); + if (__glibc_unlikely (err != 0)) + { + __nptl_deallocate_stack (pd); + retval = err == ENOMEM ? EAGAIN : err; + goto out; + } + /* Copy the stack guard canary. */ #ifdef THREAD_COPY_STACK_GUARD THREAD_COPY_STACK_GUARD (pd); diff --git a/sysdeps/aarch64/libc-shadow-stack.h b/sysdeps/aarch64/libc-shadow-stack.h new file mode 100644 index 0000000000..d55a23cff5 --- /dev/null +++ b/sysdeps/aarch64/libc-shadow-stack.h @@ -0,0 +1,46 @@ +/* libc-internal interfaces for shadow stack support. + Copyright (C) 2025 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 _AARCH64_LIBC_SHADOW_STACK_H +#define _AARCH64_LIBC_SHADOW_STACK_H 1 + +#include +#include "aarch64-gcs.h" + +#define THREAD_ALLOC_SHADOW_STACK(pd, stacksize) \ + thread_alloc_shadow_stack (pd, stacksize) + +static inline int +thread_alloc_shadow_stack (struct pthread *pd, size_t stacksize) +{ + struct gcs_record gcs; + if (!has_gcs ()) + return 0; + if (!GLRO (dl_aarch64_cpu_features).clone3_has_shadow_stack) + return 0; + if (__alloc_gcs (stacksize, &gcs) != NULL) + { + pd->shadow_stack_base = gcs.gcs_base; + pd->shadow_stack_token = gcs.gcs_token; + pd->shadow_stack_size = gcs.gcs_size; + } + /* Ignore errors: leave GCS allocation to the kernel. */ + return 0; +} + +#endif diff --git a/sysdeps/generic/libc-shadow-stack.h b/sysdeps/generic/libc-shadow-stack.h new file mode 100644 index 0000000000..09f8ca5175 --- /dev/null +++ b/sysdeps/generic/libc-shadow-stack.h @@ -0,0 +1,25 @@ +/* libc-internal interfaces for shadow stack support. + Copyright (C) 2025 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 _GENERIC_LIBC_SHADOW_STACK_H +#define _GENERIC_LIBC_SHADOW_STACK_H 1 + +/* Allocate shadow stack if supported, returns an error code. */ +#define THREAD_ALLOC_SHADOW_STACK(pd, stacksize) 0 + +#endif From patchwork Tue Jun 10 15:13:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Khrustalev X-Patchwork-Id: 114152 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 43E47382C083 for ; Tue, 10 Jun 2025 15:16:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 43E47382C083 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id E0258382D2BF for ; Tue, 10 Jun 2025 15:13:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E0258382D2BF Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E0258382D2BF Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568422; cv=none; b=HPqvajRqpa8So7RFEvuUuBFLMoX9azVii9FUmdryYmgAjNn8vZfsy/Yrt2Nk7VJcwJu9m9+Q398UwF+eugxR9ASiD7jRWYn5aogMq/oEfmmhgTCNsC1ZAS+7pgXdbjhemDDUEc+tviOXhchzIA/0HhuRz/S+DTUccSP8wo8oTpw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749568422; c=relaxed/simple; bh=Cf0IuwEWw7Ho4VMDUq2xYZzwl+Gf0QbF4obPGqE1IcI=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=Iq6Yt5mMXluQVUvwApmJuqlmeG2wvJm51AqRkQldAv2cxP3paHd5/BE/oOdovqxjQx7kMTK0/QSjOt7WR4wfJkEm5RiG16Cq+gcSk1VKTkOnIqmcA41sPLINkfepOkrFAwUUkEG8ME/rLeNQ94xH+EoTZiAHZzZAKg73JGbQhII= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E0258382D2BF Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5B978175D; Tue, 10 Jun 2025 08:13:22 -0700 (PDT) Received: from udebian.localdomain (unknown [10.1.37.41]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 584F73F59E; Tue, 10 Jun 2025 08:13:40 -0700 (PDT) From: Yury Khrustalev To: libc-alpha@sourceware.org Cc: Rick Edgecombe , Mark Brown , Deepak Gupta , Adhemerval Zanella Netto , Wilco Dijkstra , Carlos O'Donell , Florian Weimer , Szabolcs Nagy Subject: [RFC 5/5] aarch64: GCS: add clone3 test for shadow stack Date: Tue, 10 Jun 2025 16:13:20 +0100 Message-Id: <20250610151320.885131-6-yury.khrustalev@arm.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250610151320.885131-1-yury.khrustalev@arm.com> References: <20250610151320.885131-1-yury.khrustalev@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org If GCS is available check that new thread is created with a shadow stack allocated by Glibc. --- sysdeps/unix/sysv/linux/aarch64/Makefile | 9 ++ .../unix/sysv/linux/aarch64/tst-gcs-clone3.c | 118 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/aarch64/tst-gcs-clone3.c diff --git a/sysdeps/unix/sysv/linux/aarch64/Makefile b/sysdeps/unix/sysv/linux/aarch64/Makefile index 15a2b4471d..6e45788941 100644 --- a/sysdeps/unix/sysv/linux/aarch64/Makefile +++ b/sysdeps/unix/sysv/linux/aarch64/Makefile @@ -50,12 +50,17 @@ gcs-tests-static = \ tests += \ $(gcs-tests-dynamic) \ $(gcs-tests-static) \ + tst-gcs-clone3 \ # tests tests-static += \ $(gcs-tests-static) \ # tests-static +tests-internal += \ + tst-gcs-clone3 \ + # tests-internal + define run-gcs-abort-test $(test-wrapper-env) $(run-program-env) \ $(tst-gcs-$*-abort-ENV) $(host-test-program-cmd) @@ -80,6 +85,8 @@ LDFLAGS-tst-gcs-optional-static-on += -Wl,-z gcs=always LDFLAGS-tst-gcs-optional-static-off += -Wl,-z gcs=never LDFLAGS-tst-gcs-override-static += -Wl,-z gcs=never +LDFLAGS-tst-gcs-clone3 += -Wl,-z gcs=always + tst-gcs-disabled-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_gcs=0 tst-gcs-enforced-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_gcs=1 tst-gcs-enforced-abort-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_gcs=1 @@ -94,6 +101,8 @@ tst-gcs-optional-static-on-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_gcs=2 tst-gcs-optional-static-off-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_gcs=2 tst-gcs-override-static-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_gcs=3 +tst-gcs-clone3-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_gcs=1 + # force one of the dependencies to be unmarked LDFLAGS-tst-gcs-mod2.so += -Wl,-z gcs=never diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-gcs-clone3.c b/sysdeps/unix/sysv/linux/aarch64/tst-gcs-clone3.c new file mode 100644 index 0000000000..3a1c596f9d --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/tst-gcs-clone3.c @@ -0,0 +1,118 @@ +/* Check clone3 uses shadow stack allocated by Glibc when + GCS is enabled and shadow stack is supported. + Copyright (C) 2025 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 + . */ + +#include "tst-gcs-helper.h" + +#include +#include +#include +#include + +#include +#include +#include + +static void * +fun (void *arg) +{ + pthread_t self = pthread_self (); + struct pthread *pd = (struct pthread *)self; + uint64_t token = (uint64_t)pd->shadow_stack_token; + uint64_t base = (uint64_t)pd->shadow_stack_base; + uint64_t top = base + pd->shadow_stack_size; + + /* If clone3 does not support shadow stack, this pointer + will not be initialised and test should give the + UNSUPPORTED result. */ + if (base == 0) + { + puts ("shadow stack was not allocated by Glibc"); + exit (EXIT_UNSUPPORTED); + } + printf ("shadow stack top: %016lx\n", top); + printf ("shadow stack token: %016lx\n", token); + + /* This macro guard is for the sake of compilers that don't + yet have the __builtin_aarch64_gcspr() builtin so that + the test could compiler regardless. */ +#if __ARM_FEATURE_GCS_DEFAULT + /* Check that current shadow stack pointer has correct value. */ + uint64_t gcspr = (uint64_t)__builtin_aarch64_gcspr (); + printf ("current shadow stack: %016lx\n", gcspr); + TEST_VERIFY (gcspr < token); +#else + uint64_t gcspr = 0; +#endif + TEST_VERIFY (token < top); + TEST_VERIFY (base < token); + + printf ("shadow stack base: %016lx\n", base); + + return (void *)gcspr; +} + +static void +handler (int signum, siginfo_t *info, void *ptr) +{ + TEST_VERIFY (signum == SIGSEGV); + write (STDOUT_FILENO, "in signal handler\n", 18); + exit(0); +} + +static int +do_test (void) +{ + /* Check if GCS could possibly be enabled. */ + if (!(getauxval (AT_HWCAP) & HWCAP_GCS) || !__check_gcs_status ()) + { + puts ("kernel or CPU does not support GCS or GCS is disabled"); + return EXIT_UNSUPPORTED; + } + pthread_t th; + if (pthread_create (&th, NULL, fun, NULL) != 0) + { + perror ("pthread_create"); + TEST_VERIFY_EXIT (false); + } + void *gcspr; + if (pthread_join (th, &gcspr)) + { + perror ("pthread_join"); + TEST_VERIFY_EXIT (false); + } + + /* Check that if shadow stack was used, it has been freed and is + not accessible after the thread has finished. */ + if (gcspr) + { + struct sigaction sa; + memset (&sa, 0, sizeof (sa)); + sa.sa_sigaction = handler; + sigaction (SIGSEGV, &sa, NULL); + int *p = gcspr; + printf ("reading from shadow stack: %d\n", *p); + /* Unreachable. */ + TEST_VERIFY (false); + __builtin_unreachable (); + } + + return 0; +} + +#include