[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250424-v5_user_cfi_series-v13-21-971437de586a@rivosinc.com>
Date: Thu, 24 Apr 2025 00:20:36 -0700
From: Deepak Gupta <debug@...osinc.com>
To: Thomas Gleixner <tglx@...utronix.de>, Ingo Molnar <mingo@...hat.com>,
Borislav Petkov <bp@...en8.de>, Dave Hansen <dave.hansen@...ux.intel.com>,
x86@...nel.org, "H. Peter Anvin" <hpa@...or.com>,
Andrew Morton <akpm@...ux-foundation.org>,
"Liam R. Howlett" <Liam.Howlett@...cle.com>,
Vlastimil Babka <vbabka@...e.cz>,
Lorenzo Stoakes <lorenzo.stoakes@...cle.com>,
Paul Walmsley <paul.walmsley@...ive.com>,
Palmer Dabbelt <palmer@...belt.com>, Albert Ou <aou@...s.berkeley.edu>,
Conor Dooley <conor@...nel.org>, Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>, Arnd Bergmann <arnd@...db.de>,
Christian Brauner <brauner@...nel.org>,
Peter Zijlstra <peterz@...radead.org>, Oleg Nesterov <oleg@...hat.com>,
Eric Biederman <ebiederm@...ssion.com>, Kees Cook <kees@...nel.org>,
Jonathan Corbet <corbet@....net>, Shuah Khan <shuah@...nel.org>,
Jann Horn <jannh@...gle.com>, Conor Dooley <conor+dt@...nel.org>,
Miguel Ojeda <ojeda@...nel.org>, Alex Gaynor <alex.gaynor@...il.com>,
Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <benno.lossin@...ton.me>,
Andreas Hindborg <a.hindborg@...nel.org>, Alice Ryhl <aliceryhl@...gle.com>,
Trevor Gross <tmgross@...ch.edu>
Cc: linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org,
linux-mm@...ck.org, linux-riscv@...ts.infradead.org,
devicetree@...r.kernel.org, linux-arch@...r.kernel.org,
linux-doc@...r.kernel.org, linux-kselftest@...r.kernel.org,
alistair.francis@....com, richard.henderson@...aro.org, jim.shu@...ive.com,
andybnac@...il.com, kito.cheng@...ive.com, charlie@...osinc.com,
atishp@...osinc.com, evan@...osinc.com, cleger@...osinc.com,
alexghiti@...osinc.com, samitolvanen@...gle.com, broonie@...nel.org,
rick.p.edgecombe@...el.com, rust-for-linux@...r.kernel.org,
Deepak Gupta <debug@...osinc.com>
Subject: [PATCH v13 21/28] riscv: kernel command line option to opt out of
user cfi
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@...osinc.com>
---
Documentation/admin-guide/kernel-parameters.txt | 8 ++++
arch/riscv/include/asm/usercfi.h | 7 +++
arch/riscv/kernel/usercfi.c | 59 ++++++++++++++++++++-----
3 files changed, 63 insertions(+), 11 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index fb8752b42ec8..76a5ceb59c2f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -6192,6 +6192,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 361f59edbdef..0177b86f6a67 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>
@@ -84,6 +88,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/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
Powered by blists - more mailing lists