From patchwork Sun Jun 28 07:02:32 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Huang X-Patchwork-Id: 137968 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6ED0B4BA2E27 for ; Sun, 28 Jun 2026 07:07:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6ED0B4BA2E27 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=VHt6gyt6 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-dy1-x132e.google.com (mail-dy1-x132e.google.com [IPv6:2607:f8b0:4864:20::132e]) by sourceware.org (Postfix) with ESMTPS id F2F0E4BA23C4 for ; Sun, 28 Jun 2026 07:02:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F2F0E4BA23C4 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org F2F0E4BA23C4 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::132e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1782630179; cv=none; b=FaSJ4+Wje7KsZ7iIV6RYlUCtWoobOX/c/JjbTZcPjld5LMqFd9x60V1cwbL9AGB0eB/zKR0LctOK/rLiWbb51XwDWTPXFVxv7fQOxEzQZ0a7s2IFbh0TLU71eGL083CnOMPsHwZ/qYdMURt5SFA0RiF5xfIveJt5ZzRBvAnJl+Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1782630179; c=relaxed/simple; bh=8R5LPZdkTKX7FfwebHlSwgZGz2yussBTZ3yxBVhFZs0=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=fSFLmXJpcL9QNw8SWpOUjv9HQ5kk2DW6aJddiGMwY5UXisphkhHcpHGmoznvAjUtA1SizpWOXTZ3BjPR/tsdkf0HFO2eIj1/jJ6Apy03nI3AZSqTmM3dGPKGoBzlRw6uoRwJwpaJ5xaUradNI5PX2rwVspjcG/2LzJ9S2KyXXcw= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=google header.b=VHt6gyt6 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F2F0E4BA23C4 Received: by mail-dy1-x132e.google.com with SMTP id 5a478bee46e88-30ca1b4b278so4282558eec.0 for ; Sun, 28 Jun 2026 00:02:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1782630178; x=1783234978; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jw6e31Z6RZh98oofDda6j/N/TjYRskK/A1c3Wz6vJPo=; b=VHt6gyt6P6QymEAZXfrkYalmJ13Ky/MAw3l8aDKlLVI4BkbgrqwlfpTQn2mT1n12vm cVYgc2tx14WbL0HlHi9x7U4KZXDUMtwFCvcrUY7Crg54P/So+JuUbULteyZDJZKJ5qUl p+9oUM6WU8V7q3fiOuiqsA1m9b/ls5jlYqZ1/REy8gDnB1nrCktGb5r6JRp0rid9ZrP2 fpPKG2L6Co5Y5HmfBNlWaINoVsWv/Vw0UMsf96ccfvxUTjJwPXd2eN+sB3vBN7+kMamg gTbHuOXH3LtYOjppo3sZCO0Q3Ig/NOidVF5hD6TgewudplRHkNHMh4vo6SdxYnr/0jnX b9Ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782630178; x=1783234978; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=jw6e31Z6RZh98oofDda6j/N/TjYRskK/A1c3Wz6vJPo=; b=B2tcWrVWaRz+CtXvWt+9V9BgJ3K4dP9xfl218pkMmf2bcWBOOOZBJtIDMqTFVuPWK+ B5SSGdrn9J2zmRogOHDuizdumOX742E2hwPpeB6wH10Ogm6bA9J2d9TMudh2tRDWGuja 9VKclzZzYu8P+nL8wTHi1y6isyboVZAGn5KdoW1aCK8CzxnymewHZkCJGHxP61hAnvIs QaJCUbDmGfg5KeDgwLbz/JPNLkzeb+xuQqaNMYiYLsy8rXGW1P3Hk6hA1yOHl1pT2YqS cWTTtc8+C570sikMbXNARCY0teKQaMiwntI/vYf7niIhuBLRl7s+nCI5DoPnRy1vgOdR 6fBg== X-Gm-Message-State: AOJu0YwfbL2qeuNQf/nca31/pbB8I36hbM99bxrmHmuLgA1r2s0hXaTk pW5Y3kDDaK2aR25IMIod2EGlC8taGyt6IoQjV9MyZUHIbbPSqajCe+lp2afKBdCkwOl4EbQqExs OyKJmDOrttCl9711gex2Zxc52ioB6y/xR80RST+fIOiA+IPY9R6LdhwRZ86kJw4XvKdMN5n4jvy kVdW8fsRdLEQbN8s6DYSnNEBQqEWzskARiBi5CBPrV1SlVkj2X1+8= X-Gm-Gg: AfdE7clUy12CrHApRLHErycZhGQh9OqMmjOn61b08oFOfyaKQcTx/cWOhlHQe6AcuuO Z6bnZw+D8GDP4pMgDVVjUwltiyVd5c1O2lACYlr1I3WImDGeqSfLElSOP2TXokYQmZfq768Nj9m Y269Ectp63A8F6GW3Rd2QtMa7hZzKERRO9ESTnTJUVNo5DhiaxZiIGxbSdwfx+dRVsVPS/ThDpN as2o6f20hWPb60xdOIilsa8Al7X5bspaT0BX3OTKmS/sqy5e5cWX7AFKBfF5NNt46Ksa6HTu7oQ M7X3xEwLGTLa9aU4mYSXfYznYwSiA6lP1XcqPy306VcQbJVVxVRFZxt9OjImgbQrjF8EQm+xbNH hzmecJd5qGn2QpDO/a87scZoLM7iduCuJjs5syWS3FbovR+SdhRkU0MpK4qSdWRyDU2USKd+zE0 1VbSY99g9C444Z/qYpPcA0ueF4+30CaQ== X-Received: by 2002:a05:7300:3207:b0:30c:ab4d:382d with SMTP id 5a478bee46e88-30cab4d3bf1mr5611623eec.36.1782630177687; Sun, 28 Jun 2026 00:02:57 -0700 (PDT) Received: from sw08.internal.sifive.com ([4.53.31.132]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30c7c8afc91sm35435166eec.14.2026.06.28.00.02.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jun 2026 00:02:57 -0700 (PDT) From: Jesse Huang To: libc-alpha@sourceware.org Cc: andrew@sifive.com, darius@bluespec.com, debug@rivosinc.com, jeffreyalaw@gmail.com, kito.cheng@sifive.com, palmer@dabbelt.com, schwab@suse.de, Jesse Huang Subject: [PATCH v5 07/16] riscv/cfi: Enable CFI on static binaries Date: Sun, 28 Jun 2026 00:02:32 -0700 Message-Id: <20260628070241.88310-8-jesse.huang@sifive.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20260628070241.88310-1-jesse.huang@sifive.com> References: <20260628070241.88310-1-jesse.huang@sifive.com> MIME-Version: 1.0 X-Spam-Status: No, score=-13.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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 For static binaries, CFI is enabled inside ARCH_SETUP_TLS. A macro enables shadow stack early enough to prevent shadow stack underflow on return, and _dl_cfi_setup_features enables landing pad. The code scans the program headers backward to find the first PT_GNU_PROPERTY note, then enables CFI features corresponding to the feature bits. Co-authored-by: Deepak Gupta --- sysdeps/riscv/Makefile | 1 + sysdeps/riscv/dl-cfi.c | 36 +++++++++++ sysdeps/riscv/dl-machine.h | 6 ++ sysdeps/riscv/dl-prop.h | 65 +++++++++++++++++++ sysdeps/riscv/libc-start.h | 88 ++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/riscv/dl-cfi.h | 20 ++++++ 6 files changed, 216 insertions(+) create mode 100644 sysdeps/riscv/dl-cfi.c create mode 100644 sysdeps/riscv/dl-prop.h create mode 100644 sysdeps/riscv/libc-start.h create mode 100644 sysdeps/unix/sysv/linux/riscv/dl-cfi.h diff --git a/sysdeps/riscv/Makefile b/sysdeps/riscv/Makefile index 99976fddad..4752bdb1a0 100644 --- a/sysdeps/riscv/Makefile +++ b/sysdeps/riscv/Makefile @@ -18,6 +18,7 @@ endif # Enable RISC-V CFI ifeq (yes,$(riscv-enable-cfi)) +sysdep-dl-routines += dl-cfi CFLAGS-.o += -fcf-protection=full CFLAGS-.os += -fcf-protection=full CFLAGS-.op += -fcf-protection=full diff --git a/sysdeps/riscv/dl-cfi.c b/sysdeps/riscv/dl-cfi.c new file mode 100644 index 0000000000..216e8f12c0 --- /dev/null +++ b/sysdeps/riscv/dl-cfi.c @@ -0,0 +1,36 @@ +/* RISC-V CFI extensions (zicfilp/zicfiss) functions. + Copyright (C) 2026 Free Software Foundation, Inc. + + 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 +#include +#include +#include +#include +#include + +attribute_hidden void +_dl_cfi_setup_features (unsigned int feature_1) +{ + /* Since prctl could fail to enable some features + use prctl to get enabled features again and sync it back. */ +#ifdef __riscv_landing_pad + if (feature_1 & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) + INTERNAL_SYSCALL_CALL (prctl, PR_SET_CFI, PR_CFI_BRANCH_LANDING_PADS, + PR_CFI_ENABLE, 0, 0, 0); +#endif /* __riscv_landing_pad */ + /* FIXME: Read enabled features from kernel and re-sync */ +} diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h index 05992c8705..b7b9959d58 100644 --- a/sysdeps/riscv/dl-machine.h +++ b/sysdeps/riscv/dl-machine.h @@ -28,6 +28,12 @@ #include #include #include +#if defined(__riscv_landing_pad) || defined(__riscv_shadow_stack) +# include +extern void _dl_cfi_setup_features (unsigned int features); +#else +# define RTLD_START_ENABLE_RISCV_CFI +#endif /* This is a marker to remind us to add real expansion to setup the label for the function signature label scheme in the future */ #ifdef __riscv_landing_pad_unlabeled diff --git a/sysdeps/riscv/dl-prop.h b/sysdeps/riscv/dl-prop.h new file mode 100644 index 0000000000..a183d3148a --- /dev/null +++ b/sysdeps/riscv/dl-prop.h @@ -0,0 +1,65 @@ +/* Support for GNU properties. RISC-V version. + Copyright (C) 2026 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 _DL_PROP_H +#define _DL_PROP_H + +static inline void __attribute__ ((always_inline)) +_rtld_main_check (struct link_map *m, const char *program) +{ +} + +static inline void __attribute__ ((always_inline)) +_dl_open_check (struct link_map *m, int dl_openmode) +{ +} + +static inline void __attribute__ ((always_inline)) +_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph) +{ +} + +static inline int +_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type, + uint32_t datasz, void *data) +{ + /* FIXME: Detect cpu features after we have it implemented in glibc */ + + if (type == GNU_PROPERTY_RISCV_FEATURE_1_AND) + { + /* Stop if the property note is ill-formed. */ + if (datasz != 4) + return -1; + +#if defined(__riscv_landing_pad) || defined(__riscv_shadow_stack) + unsigned int feature_1 = *(unsigned int *) data; +#endif +#ifdef __riscv_landing_pad + if (feature_1 & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) + l->l_riscv_feature_1_and |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED; +#endif +#ifdef __riscv_shadow_stack + if (feature_1 & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) + l->l_riscv_feature_1_and |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS; +#endif + } + /* Continue. */ + return 1; +} + +#endif /* _DL_PROP_H */ diff --git a/sysdeps/riscv/libc-start.h b/sysdeps/riscv/libc-start.h new file mode 100644 index 0000000000..91d094cfb5 --- /dev/null +++ b/sysdeps/riscv/libc-start.h @@ -0,0 +1,88 @@ +/* RISC-V libc main startup. + Copyright (C) 2026 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 SHARED +# define ARCH_SETUP_IREL() apply_irel () +# define ARCH_APPLY_IREL() + +# if defined(__riscv_landing_pad) || defined(__riscv_shadow_stack) +/* Get shadow stack features enabled in the static executable. */ +# include +# include +extern void _dl_cfi_setup_features (unsigned int); + +static inline unsigned int +get_cfi_feature (void) +{ + unsigned int cfi_feature = 0; + /* FIXME: check if cfi feature is supported by CPU */ + struct link_map *main_map = _dl_get_dl_main_map (); + + /* Scan program headers backward to check PT_GNU_PROPERTY early for + feature bits on static executable. */ + const ElfW(Phdr) *phdr = GL(dl_phdr); + const ElfW(Phdr) *ph; + for (ph = phdr + GL(dl_phnum); ph != phdr; ph--) + if (ph[-1].p_type == PT_GNU_PROPERTY) + { + _dl_process_pt_gnu_property (main_map, -1, &ph[-1]); + /* Enable landing pad and shstk only if they are enabled on a static + executable. */ + /* FIXME: change to &= to mask off other features after cpu_feature + is implemented */ + cfi_feature = (main_map->l_riscv_feature_1_and + & (GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED + | GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS)); + + GL(dl_riscv_feature_1) = cfi_feature; + return cfi_feature; + } + GL(dl_riscv_feature_1) = 0; + return 0; +} + +/* The function using this macro to enable shadow stack must not return + to avoid shadow stack underflow. */ +# ifdef __riscv_shadow_stack +# define ENABLE_RISCV_SHADOW_STACK \ + do \ + { \ + if (feature & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) \ + { \ + INTERNAL_SYSCALL_CALL (prctl, PR_SET_SHADOW_STACK_STATUS, \ + PR_SHADOW_STACK_ENABLE, 0, 0, 0); \ + } \ + } \ + while (0) +# else +# define ENABLE_RISCV_SHADOW_STACK +# endif + +# define ARCH_SETUP_TLS() \ + { \ + __libc_setup_tls (); \ + \ + unsigned int feature = get_cfi_feature (); \ + ENABLE_RISCV_SHADOW_STACK; \ + /* Landing pad will be enabled in _dl_cfi_setup_features */ \ + _dl_cfi_setup_features(feature); \ + } +# else +# define ARCH_SETUP_TLS() __libc_setup_tls () +# endif /* __riscv_landing_pad || __riscv_shadow_stack */ +#endif /* !SHARED */ diff --git a/sysdeps/unix/sysv/linux/riscv/dl-cfi.h b/sysdeps/unix/sysv/linux/riscv/dl-cfi.h new file mode 100644 index 0000000000..86ba6eaafb --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/dl-cfi.h @@ -0,0 +1,20 @@ +/* Linux/RISC-V CFI initializers function. + Copyright (C) 2026 Free Software Foundation, Inc. + + 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 + . */ + +/* FIXME: Should be remove after they are included in the kernel header */ +#include +#include