From: Deepak Gupta <debug@rivosinc.com>
To: "Thomas Gleixner" <tglx@linutronix.de>,
"Ingo Molnar" <mingo@redhat.com>,
"Borislav Petkov" <bp@alien8.de>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Liam R. Howlett" <Liam.Howlett@oracle.com>,
"Vlastimil Babka" <vbabka@suse.cz>,
"Lorenzo Stoakes" <lorenzo.stoakes@oracle.com>,
"Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Conor Dooley" <conor@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Arnd Bergmann" <arnd@arndb.de>,
"Christian Brauner" <brauner@kernel.org>,
"Peter Zijlstra" <peterz@infradead.org>,
"Oleg Nesterov" <oleg@redhat.com>,
"Eric Biederman" <ebiederm@xmission.com>,
"Kees Cook" <kees@kernel.org>, "Jonathan Corbet" <corbet@lwn.net>,
"Shuah Khan" <shuah@kernel.org>, "Jann Horn" <jannh@google.com>,
"Conor Dooley" <conor+dt@kernel.org>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Benno Lossin" <lossin@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-mm@kvack.org, linux-riscv@lists.infradead.org,
devicetree@vger.kernel.org, linux-arch@vger.kernel.org,
linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org,
alistair.francis@wdc.com, richard.henderson@linaro.org,
jim.shu@sifive.com, andybnac@gmail.com, kito.cheng@sifive.com,
charlie@rivosinc.com, atishp@rivosinc.com, evan@rivosinc.com,
cleger@rivosinc.com, alexghiti@rivosinc.com,
samitolvanen@google.com, broonie@kernel.org,
rick.p.edgecombe@intel.com, rust-for-linux@vger.kernel.org,
Deepak Gupta <debug@rivosinc.com>
Subject: [PATCH v18 21/27] riscv: kernel command line option to opt out of user cfi
Date: Fri, 11 Jul 2025 12:46:26 -0700 [thread overview]
Message-ID: <20250711-v5_user_cfi_series-v18-21-a8ee62f9f38e@rivosinc.com> (raw)
In-Reply-To: <20250711-v5_user_cfi_series-v18-0-a8ee62f9f38e@rivosinc.com>
This commit adds a kernel command line option using which user cfi can be
disabled. User backward cfi and forward cfi can be enabled independently.
Kernel command line parameter "riscv_nousercfi" can take below values:
- "all" : Disable forward and backward cfi both.
- "bcfi" : Disable backward cfi.
- "fcfi" : Disable forward cfi
Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
Documentation/admin-guide/kernel-parameters.txt | 8 ++++
arch/riscv/include/asm/usercfi.h | 7 +++
arch/riscv/kernel/cpufeature.c | 9 +++-
arch/riscv/kernel/usercfi.c | 59 ++++++++++++++++++++-----
4 files changed, 70 insertions(+), 13 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f1f2c0874da9..62aee3fc2256 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -6312,6 +6312,14 @@
replacement properties are not found. See the Kconfig
entry for RISCV_ISA_FALLBACK.
+ riscv_nousercfi=
+ all Disable user cfi ABI to userspace even if cpu extension
+ are available.
+ bcfi Disable user backward cfi ABI to userspace even if
+ shadow stack extension is available.
+ fcfi Disable user forward cfi ABI to userspace even if landing
+ pad extension is available.
+
ro [KNL] Mount root device read-only on boot
rodata= [KNL,EARLY]
diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
index 54add512a4dc..afef69910601 100644
--- a/arch/riscv/include/asm/usercfi.h
+++ b/arch/riscv/include/asm/usercfi.h
@@ -5,6 +5,10 @@
#ifndef _ASM_RISCV_USERCFI_H
#define _ASM_RISCV_USERCFI_H
+#define CMDLINE_DISABLE_RISCV_USERCFI_FCFI 1
+#define CMDLINE_DISABLE_RISCV_USERCFI_BCFI 2
+#define CMDLINE_DISABLE_RISCV_USERCFI 3
+
#ifndef __ASSEMBLY__
#include <linux/types.h>
#include <linux/prctl.h>
@@ -83,6 +87,9 @@ void set_indir_lp_lock(struct task_struct *task);
#endif /* CONFIG_RISCV_USER_CFI */
+bool is_user_shstk_enabled(void);
+bool is_user_lpad_enabled(void);
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_RISCV_USERCFI_H */
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index d38136672650..49eaf501faec 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -28,6 +28,7 @@
#include <asm/vector.h>
#include <asm/vendor_extensions.h>
#include <asm/vendor_extensions/thead.h>
+#include <asm/usercfi.h>
#define NUM_ALPHA_EXTS ('z' - 'a' + 1)
@@ -45,6 +46,8 @@ struct riscv_isainfo hart_isa[NR_CPUS];
u32 thead_vlenb_of;
+extern unsigned int riscv_nousercfi;
+
/**
* riscv_isa_extension_base() - Get base extension word
*
@@ -277,7 +280,8 @@ static int riscv_ext_svadu_validate(const struct riscv_isa_ext_data *data,
static int riscv_cfilp_validate(const struct riscv_isa_ext_data *data,
const unsigned long *isa_bitmap)
{
- if (!IS_ENABLED(CONFIG_RISCV_USER_CFI))
+ if (!IS_ENABLED(CONFIG_RISCV_USER_CFI) ||
+ (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI))
return -EINVAL;
return 0;
@@ -286,7 +290,8 @@ static int riscv_cfilp_validate(const struct riscv_isa_ext_data *data,
static int riscv_cfiss_validate(const struct riscv_isa_ext_data *data,
const unsigned long *isa_bitmap)
{
- if (!IS_ENABLED(CONFIG_RISCV_USER_CFI))
+ if (!IS_ENABLED(CONFIG_RISCV_USER_CFI) ||
+ (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI))
return -EINVAL;
return 0;
diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
index 8bc3e1e3f712..5ef357f43ad7 100644
--- a/arch/riscv/kernel/usercfi.c
+++ b/arch/riscv/kernel/usercfi.c
@@ -17,6 +17,8 @@
#include <asm/csr.h>
#include <asm/usercfi.h>
+unsigned int riscv_nousercfi;
+
#define SHSTK_ENTRY_SIZE sizeof(void *)
bool is_shstk_enabled(struct task_struct *task)
@@ -59,7 +61,7 @@ unsigned long get_active_shstk(struct task_struct *task)
void set_shstk_status(struct task_struct *task, bool enable)
{
- if (!cpu_supports_shadow_stack())
+ if (!is_user_shstk_enabled())
return;
task->thread_info.user_cfi_state.ubcfi_en = enable ? 1 : 0;
@@ -89,7 +91,7 @@ bool is_indir_lp_locked(struct task_struct *task)
void set_indir_lp_status(struct task_struct *task, bool enable)
{
- if (!cpu_supports_indirect_br_lp_instr())
+ if (!is_user_lpad_enabled())
return;
task->thread_info.user_cfi_state.ufcfi_en = enable ? 1 : 0;
@@ -259,7 +261,7 @@ SYSCALL_DEFINE3(map_shadow_stack, unsigned long, addr, unsigned long, size, unsi
bool set_tok = flags & SHADOW_STACK_SET_TOKEN;
unsigned long aligned_size = 0;
- if (!cpu_supports_shadow_stack())
+ if (!is_user_shstk_enabled())
return -EOPNOTSUPP;
/* Anything other than set token should result in invalid param */
@@ -306,7 +308,7 @@ unsigned long shstk_alloc_thread_stack(struct task_struct *tsk,
unsigned long addr, size;
/* If shadow stack is not supported, return 0 */
- if (!cpu_supports_shadow_stack())
+ if (!is_user_shstk_enabled())
return 0;
/*
@@ -352,7 +354,7 @@ void shstk_release(struct task_struct *tsk)
{
unsigned long base = 0, size = 0;
/* If shadow stack is not supported or not enabled, nothing to release */
- if (!cpu_supports_shadow_stack() || !is_shstk_enabled(tsk))
+ if (!is_user_shstk_enabled() || !is_shstk_enabled(tsk))
return;
/*
@@ -381,7 +383,7 @@ int arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *st
{
unsigned long bcfi_status = 0;
- if (!cpu_supports_shadow_stack())
+ if (!is_user_shstk_enabled())
return -EINVAL;
/* this means shadow stack is enabled on the task */
@@ -395,7 +397,7 @@ int arch_set_shadow_stack_status(struct task_struct *t, unsigned long status)
unsigned long size = 0, addr = 0;
bool enable_shstk = false;
- if (!cpu_supports_shadow_stack())
+ if (!is_user_shstk_enabled())
return -EINVAL;
/* Reject unknown flags */
@@ -448,7 +450,7 @@ int arch_lock_shadow_stack_status(struct task_struct *task,
unsigned long arg)
{
/* If shtstk not supported or not enabled on task, nothing to lock here */
- if (!cpu_supports_shadow_stack() ||
+ if (!is_user_shstk_enabled() ||
!is_shstk_enabled(task) || arg != 0)
return -EINVAL;
@@ -461,7 +463,7 @@ int arch_get_indir_br_lp_status(struct task_struct *t, unsigned long __user *sta
{
unsigned long fcfi_status = 0;
- if (!cpu_supports_indirect_br_lp_instr())
+ if (!is_user_lpad_enabled())
return -EINVAL;
/* indirect branch tracking is enabled on the task or not */
@@ -474,7 +476,7 @@ int arch_set_indir_br_lp_status(struct task_struct *t, unsigned long status)
{
bool enable_indir_lp = false;
- if (!cpu_supports_indirect_br_lp_instr())
+ if (!is_user_lpad_enabled())
return -EINVAL;
/* indirect branch tracking is locked and further can't be modified by user */
@@ -498,7 +500,7 @@ int arch_lock_indir_br_lp_status(struct task_struct *task,
* If indirect branch tracking is not supported or not enabled on task,
* nothing to lock here
*/
- if (!cpu_supports_indirect_br_lp_instr() ||
+ if (!is_user_lpad_enabled() ||
!is_indir_lp_enabled(task) || arg != 0)
return -EINVAL;
@@ -506,3 +508,38 @@ int arch_lock_indir_br_lp_status(struct task_struct *task,
return 0;
}
+
+bool is_user_shstk_enabled(void)
+{
+ return (cpu_supports_shadow_stack() &&
+ !(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI));
+}
+
+bool is_user_lpad_enabled(void)
+{
+ return (cpu_supports_indirect_br_lp_instr() &&
+ !(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI));
+}
+
+static int __init setup_global_riscv_enable(char *str)
+{
+ if (strcmp(str, "all") == 0)
+ riscv_nousercfi = CMDLINE_DISABLE_RISCV_USERCFI;
+
+ if (strcmp(str, "fcfi") == 0)
+ riscv_nousercfi |= CMDLINE_DISABLE_RISCV_USERCFI_FCFI;
+
+ if (strcmp(str, "bcfi") == 0)
+ riscv_nousercfi |= CMDLINE_DISABLE_RISCV_USERCFI_BCFI;
+
+ if (riscv_nousercfi)
+ pr_info("riscv user cfi disabled via cmdline"
+ "shadow stack status : %s, landing pad status : %s\n",
+ (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI) ? "disabled" :
+ "enabled", (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI) ?
+ "disabled" : "enabled");
+
+ return 1;
+}
+
+__setup("riscv_nousercfi=", setup_global_riscv_enable);
--
2.43.0
next prev parent reply other threads:[~2025-07-11 19:47 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-11 19:46 [PATCH v18 00/27] riscv control-flow integrity for usermode Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 01/27] mm: VM_SHADOW_STACK definition for riscv Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 02/27] dt-bindings: riscv: zicfilp and zicfiss in dt-bindings (extensions.yaml) Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 03/27] riscv: zicfiss / zicfilp enumeration Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 04/27] riscv: zicfiss / zicfilp extension csr and bit definitions Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 05/27] riscv: usercfi state for task and save/restore of CSR_SSP on trap entry/exit Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 06/27] riscv/mm : ensure PROT_WRITE leads to VM_READ | VM_WRITE Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 07/27] riscv/mm: manufacture shadow stack pte Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 08/27] riscv/mm: teach pte_mkwrite to manufacture shadow stack PTEs Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 09/27] riscv/mm: write protect and shadow stack Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 10/27] riscv/mm: Implement map_shadow_stack() syscall Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 11/27] riscv/shstk: If needed allocate a new shadow stack on clone Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 12/27] riscv: Implements arch agnostic shadow stack prctls Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 13/27] prctl: arch-agnostic prctl for indirect branch tracking Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 14/27] riscv: Implements arch agnostic indirect branch tracking prctls Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 15/27] riscv/traps: Introduce software check exception and uprobe handling Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 16/27] riscv: signal: abstract header saving for setup_sigcontext Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 17/27] riscv/signal: save and restore of shadow stack for signal Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 18/27] riscv/kernel: update __show_regs to print shadow stack register Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 19/27] riscv/ptrace: riscv cfi status and state via ptrace and in core files Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 20/27] riscv/hwprobe: zicfilp / zicfiss enumeration in hwprobe Deepak Gupta
2025-07-11 19:46 ` Deepak Gupta [this message]
2025-07-11 19:46 ` [PATCH v18 22/27] riscv: enable kernel access to shadow stack memory via FWFT sbi call Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 23/27] arch/riscv: compile vdso with landing pad and shadow stack note Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 24/27] riscv: create a config for shadow stack and landing pad instr support Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 25/27] riscv: Documentation for landing pad / indirect branch tracking Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 26/27] riscv: Documentation for shadow stack on riscv Deepak Gupta
2025-07-11 19:46 ` [PATCH v18 27/27] kselftest/riscv: kselftest for user mode cfi Deepak Gupta
2025-07-11 20:25 ` [PATCH v18 00/27] riscv control-flow integrity for usermode Deepak Gupta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250711-v5_user_cfi_series-v18-21-a8ee62f9f38e@rivosinc.com \
--to=debug@rivosinc.com \
--cc=Liam.Howlett@oracle.com \
--cc=a.hindborg@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=alex.gaynor@gmail.com \
--cc=alexghiti@rivosinc.com \
--cc=aliceryhl@google.com \
--cc=alistair.francis@wdc.com \
--cc=andybnac@gmail.com \
--cc=aou@eecs.berkeley.edu \
--cc=arnd@arndb.de \
--cc=atishp@rivosinc.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=bp@alien8.de \
--cc=brauner@kernel.org \
--cc=broonie@kernel.org \
--cc=charlie@rivosinc.com \
--cc=cleger@rivosinc.com \
--cc=conor+dt@kernel.org \
--cc=conor@kernel.org \
--cc=corbet@lwn.net \
--cc=dave.hansen@linux.intel.com \
--cc=devicetree@vger.kernel.org \
--cc=ebiederm@xmission.com \
--cc=evan@rivosinc.com \
--cc=gary@garyguo.net \
--cc=hpa@zytor.com \
--cc=jannh@google.com \
--cc=jim.shu@sifive.com \
--cc=kees@kernel.org \
--cc=kito.cheng@sifive.com \
--cc=krzk+dt@kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-riscv@lists.infradead.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=lossin@kernel.org \
--cc=mingo@redhat.com \
--cc=ojeda@kernel.org \
--cc=oleg@redhat.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=peterz@infradead.org \
--cc=richard.henderson@linaro.org \
--cc=rick.p.edgecombe@intel.com \
--cc=robh@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=samitolvanen@google.com \
--cc=shuah@kernel.org \
--cc=tglx@linutronix.de \
--cc=tmgross@umich.edu \
--cc=vbabka@suse.cz \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).