From patchwork Tue May 26 06:16:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Huang X-Patchwork-Id: 135664 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 2D9A64BA9029 for ; Tue, 26 May 2026 06:24:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2D9A64BA9029 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=dBzVPzC5 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-dy1-x1334.google.com (mail-dy1-x1334.google.com [IPv6:2607:f8b0:4864:20::1334]) by sourceware.org (Postfix) with ESMTPS id AB7414BA23EE for ; Tue, 26 May 2026 06:18:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AB7414BA23EE 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 AB7414BA23EE Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1334 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1779776286; cv=none; b=ao0vhes2A6as/lFmdHWyrpYJ5NgIeJ2+rPb9ALymPNd2kHc7OJJ5JUBpCXO4WWSdnBdZNcAnobO5q3i5o+dBqdfKDM408zTy5hb/DB4y5M5sNsw/SwIxjD4cMPFiGKDnNYpr9jMfTvsaOFI/1IG1HBFcPI+rHQ7kzdYN5l4hoeU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1779776286; c=relaxed/simple; bh=+5ZOUOejbOpwSSl6fpsgDRRY7qPb/IX/UKxtNoh3LFw=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=jr6ugUqZn1o4APvnpb5zgC0beFLg7SD5fRI4LI9z2Z7ypMFh6aGNtEpEAkzTKY53PEyjTMJGeuPw5ie48U0pyvQH/4cO86m/ctYT5VeblZ6EQGWfifLWK5XQ9fyrQ7tPTwFcOU1IJXiYDn/Zw37+zX0x+yY7+cw47sfB29WxelY= 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=dBzVPzC5 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AB7414BA23EE Received: by mail-dy1-x1334.google.com with SMTP id 5a478bee46e88-303dbfbec77so11957012eec.0 for ; Mon, 25 May 2026 23:18:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1779776286; x=1780381086; 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=rFRoWBdPTO2Dar7JFKFI32pWZmissGUbQG0e5/Uqhl8=; b=dBzVPzC51ZJa+aE7uhNjM1QrBNXgHLFziDlzwmp14rlYpdxlQL73oItIU+QlkA2xhf IVz3A5O59f985fwXjCijtHVuFWedoSAdmNsNuTW6cmlVLpZ+cR2VRh8RZ4OIes4sprUV GmVI1/MpKY4tcaR5MMdpHhPfspWfhOKS6WyufKdUEeQbcXCF3Pl6tZgAngv0gQPTADGC K4bOc6TbfHivKqrfvPsM8lBq1Pac5/P1N/v4vtsP1aCM85+eVvDzXaIXAShzjU4H9o2c y13u0ddxJpaJ6D9KA0BReXGDEWSI9tZpspYfnrokXXGLwOx7VsIQBGVDhObCtjvez5jS KJug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779776286; x=1780381086; 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=rFRoWBdPTO2Dar7JFKFI32pWZmissGUbQG0e5/Uqhl8=; b=QusvyWoBFfmHN1As4sAdJ60bedqjvJUaRW1rj8wjzH3ewkaAstgfllYPcphJF/WGLR c5BvG8+2Bw3CfpVxKDJtcVrOmBNfsMCxbEYI8+n3bQ4qyr9sJSBt/ov5HNB6MZxYTW+D E+Iy+QkK8aaJhRQAyTkJmNaATL1syAyRQbWdHZZH0XXL4be2WbU6UxIqXdUx87HFBTwp RTbbLrUVTttaUJYhJ2/DcfoxFBeT20aHsxuu1ETtgxIPj7IkjNTgclKXC2c+zqZIPGb8 NhKitX9Ev4uRJnzclBiDoJdYkC3yL5Sx5qygGYGV5nPH/ct+/pQfwUgXXmMvy/fyU1eW A5VA== X-Gm-Message-State: AOJu0YytPsofSixn78b95ijKpduaAbpYQP/PO/fkGGbbi3/cKC+ImmB2 i1HQ1/lzv7jvEbWCZKD/YCs4Q7OR6MivPpJ6ZArNSt9AdypbfiWaJb4e6z5xuPL3JItKmWoPqAL UGaQkMGJo2e2RfCPU3Zl6WLyW+Sccqp0PRZb0b7peu5V0Fccl0hJsPcebsznCaf/kfhi4fp3lvt ZlarQxVU6MxEFIqQ6Oz/cA+AsSevzar+lnIB4zPu/ZzjnEydq5Op4= X-Gm-Gg: Acq92OG8+wNJRNx1rTtrW58tLnYfwIuu2vHIKn3oE7wRBHQumfAjVHDODTayCoYWz3O Q89/tz/teXuZOSmJrw8gcyIzdi2YouZXNrCwN8YYUef+sivG9/7mZKxTOlSR1Gt0hASivjp5v+W 4Cbn4ujK4KW/FrGAimv1Ahsg6akMtOCV6VGPC1Z3+XcHBIeuw7s0hASMqfXXFtE+bU4i2dj0DGp aS2Y3qvvp5mRq5+vTTsbEes39VqIhpLjCCPD+x2T5RzKopcYxRQDIfooWplqR1vIbU++TQbNXoV whEG/5q+5/A0OaemNb0G1y1LlAy2V4cZN2I6DklF/Zaiu7GxkcfrHX6DGU0nTHHJkIxT3OT3AlC qVjQiWwlsrsN01ZWVhOm8LhWF8PvZnnh8BSrSZ904N3g4OHg5N95rkTTPPCCTOHIu6qr87lJk7E G7GsdirtcTSbKPbsowmrrvytpDoBJUpkzE1gnUTiRJ X-Received: by 2002:a05:7300:8b1f:b0:2e0:1f09:d924 with SMTP id 5a478bee46e88-30448f30884mr8544737eec.5.1779776285476; Mon, 25 May 2026 23:18:05 -0700 (PDT) Received: from sw08.internal.sifive.com ([4.53.31.132]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30452461cb5sm14062504eec.31.2026.05.25.23.18.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 May 2026 23:18:05 -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, Jesse Huang Subject: [PATCH v4 11/17] riscv/cfi: Support locking/disabling CFI and move OS depedent code Date: Mon, 25 May 2026 23:16:57 -0700 Message-Id: <20260526061703.2188042-12-jesse.huang@sifive.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20260526061703.2188042-1-jesse.huang@sifive.com> References: <20260526061703.2188042-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, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED 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 --- sysdeps/riscv/dl-cfi.c | 40 +++++++++++----- sysdeps/unix/sysv/linux/riscv/dl-cfi.h | 65 ++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 11 deletions(-) diff --git a/sysdeps/riscv/dl-cfi.c b/sysdeps/riscv/dl-cfi.c index 275faddcc9..27ac4cff10 100644 --- a/sysdeps/riscv/dl-cfi.c +++ b/sysdeps/riscv/dl-cfi.c @@ -57,7 +57,7 @@ struct dl_cfi_info static void dl_check_legacy_object (struct link_map *m, struct dl_cfi_info *info) { - /* Iterate through the dependencies and disable if needed here */ + /* Iterate through the dependencies and record legacy objects */ struct link_map *l = NULL; unsigned int i; i = m->l_searchlist.r_nlist; @@ -86,7 +86,11 @@ dl_check_legacy_object (struct link_map *m, struct dl_cfi_info *info) | ~(GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED | GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS)); - /* Bookkeeping legacy objects */ + /* Bookkeeping first found mismatch object for both lp/ss. + These information would only be used by dlopen check for now. + A dependency with a feature on will be record as legacy if the task + did not enable the feature, however it is safe because the following + check will only be performed if the task has the feature on. */ #ifdef __riscv_landing_pad if ((info->feature_1_legacy & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) == 0 && ((info->enable_feature_1 & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) @@ -208,8 +212,8 @@ dl_cfi_check_dlopen (struct link_map *m, struct dl_cfi_info *info) _dl_signal_error (0, m->l_initfini[legacy_obj]->l_name, "dlopen", msg); if (disable_feature_1 != 0) - // FIXME: Disable CFI here - int res = -1; + { + int res = dl_cfi_disable_cfi (disable_feature_1); if (res) { msg = N_("can't disable CFI feature"); @@ -223,14 +227,29 @@ dl_cfi_check_dlopen (struct link_map *m, struct dl_cfi_info *info) 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. */ + /* Enable features. Shadow stack is enabled earlier as it should + * be enabled in a function that never returns. */ +#ifdef __riscv_landing_pad + dl_cfi_enable_lp (feature_1); +#endif /* __riscv_landing_pad */ + + /* Since we could failed to enable some features, + get enabled features from system again and sync it back. */ + int status = dl_cfi_get_cfi_status (); + GL(dl_riscv_feature_1) = status | (GL(dl_riscv_feature_1) & + ~(GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS + | GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED)); + + /* Lock features if set to always_on */ #ifdef __riscv_landing_pad - if (feature_1 & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) - INTERNAL_SYSCALL_CALL (prctl, PR_SET_INDIR_BR_LP_STATUS, - PR_INDIR_BR_LP_ENABLE, 0, 0, 0); + if (GL(dl_riscv_feature_control).lp == cfi_always_on) + dl_cfi_lock_cfi (GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED); #endif /* __riscv_landing_pad */ - /* FIXME: Read enabled features from kernel and re-sync */ +#ifdef __riscv_shadow_stack + if (GL(dl_riscv_feature_control).ss == cfi_always_on) + dl_cfi_lock_cfi (GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS); +#endif /* __riscv_shadow_stack */ + /* FIXME: Should we terminate if failed to lock under always on mode? */ } /* Enable CFI for l and its dependencies. */ @@ -287,7 +306,6 @@ _dl_cfi_check (struct link_map *l, const char *program) info.feature_1_legacy_ss = 0; #endif - info.feature_1_enabled = GL(dl_riscv_feature_1); info.feature_1_legacy = 0; #ifdef SHARED diff --git a/sysdeps/unix/sysv/linux/riscv/dl-cfi.h b/sysdeps/unix/sysv/linux/riscv/dl-cfi.h index 53df470930..9758fbf0e3 100644 --- a/sysdeps/unix/sysv/linux/riscv/dl-cfi.h +++ b/sysdeps/unix/sysv/linux/riscv/dl-cfi.h @@ -48,3 +48,68 @@ jal _dl_cfi_setup_features \n\ \n\ " + +static __always_inline int +dl_cfi_disable_cfi (unsigned int feature) { + int res = 0; +#ifdef __riscv_landing_pad + if (feature & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) + { + res = prctl (PR_SET_INDIR_BR_LP_STATUS, 0, 0, 0, 0); + if (res) + return res; + } +#endif /* __riscv_landing_pad */ +#ifdef __riscv_shadow_stack + if (feature & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) + { + res |= prctl (PR_SET_SHADOW_STACK_STATUS, 0, 0, 0, 0); + if (res) + return res; + } +#endif /* __riscv_shadow_stack */ + return 0; +} + +static __always_inline int +dl_cfi_lock_cfi (unsigned int feature) +{ + int res = 0; +#ifdef __riscv_landing_pad + if (feature & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) + res |= prctl (PR_LOCK_INDIR_BR_LP_STATUS, 0, 0, 0, 0); +#endif /* __riscv_landing_pad */ +#ifdef __riscv_shadow_stack + if (feature & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) + res |= prctl (PR_LOCK_SHADOW_STACK_STATUS, 0, 0, 0, 0); +#endif /* __riscv_shadow_stack */ + return res; +} + +static __always_inline int +dl_cfi_get_cfi_status (void) { + int status = 0; + unsigned long buf = 0; + int ret = 0; +#ifdef __riscv_landing_pad + ret = prctl (PR_GET_INDIR_BR_LP_STATUS, &buf, 0, 0, 0); + if (!ret && buf) + status |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED; +#endif /* __riscv_landing_pad */ +#ifdef __riscv_shadow_stack + ret = prctl (PR_GET_SHADOW_STACK_STATUS, &buf, 0, 0, 0); + if (!ret && buf) + status |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS; +#endif /* __riscv_shadow_stack */ + return status; +} + +#ifdef __riscv_landing_pad +static __always_inline int +dl_cfi_enable_lp (unsigned int feature) { + if (!(feature & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED)) + return -1; + return INTERNAL_SYSCALL_CALL (prctl, PR_SET_INDIR_BR_LP_STATUS, + PR_INDIR_BR_LP_ENABLE, 0, 0, 0); +} +#endif /* __riscv_landing_pad */