From: Deepak Gupta <debug@rivosinc.com>
To: paul.walmsley@sifive.com, palmer@sifive.com, conor@kernel.org,
linux-doc@vger.kernel.org, linux-riscv@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-fsdevel@vger.kernel.org, linux-mm@kvack.org,
linux-arch@vger.kernel.org, linux-kselftest@vger.kernel.org
Cc: corbet@lwn.net, palmer@dabbelt.com, aou@eecs.berkeley.edu,
robh@kernel.org, krzk+dt@kernel.org, oleg@redhat.com,
tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com,
peterz@infradead.org, akpm@linux-foundation.org, arnd@arndb.de,
ebiederm@xmission.com, kees@kernel.org, Liam.Howlett@oracle.com,
vbabka@suse.cz, lorenzo.stoakes@oracle.com, shuah@kernel.org,
brauner@kernel.org, samuel.holland@sifive.com,
debug@rivosinc.com, andy.chiu@sifive.com, jerry.shih@sifive.com,
greentime.hu@sifive.com, charlie@rivosinc.com, evan@rivosinc.com,
cleger@rivosinc.com, xiao.w.wang@intel.com,
ajones@ventanamicro.com, anup@brainfault.org,
mchitale@ventanamicro.com, atishp@rivosinc.com,
sameo@rivosinc.com, bjorn@rivosinc.com, alexghiti@rivosinc.com,
david@redhat.com, libang.li@antgroup.com, jszhang@kernel.org,
leobras@redhat.com, guoren@kernel.org, samitolvanen@google.com,
songshuaishuai@tinylab.org, costa.shul@redhat.com,
bhe@redhat.com, zong.li@sifive.com, puranjay@kernel.org,
namcaov@gmail.com, antonb@tenstorrent.com, sorear@fastmail.com,
quic_bjorande@quicinc.com, ancientmodern4@gmail.com,
ben.dooks@codethink.co.uk, quic_zhonhan@quicinc.com,
cuiyunhui@bytedance.com, yang.lee@linux.alibaba.com,
ke.zhao@shingroup.cn, sunilvl@ventanamicro.com,
tanzhasanwork@gmail.com, schwab@suse.de, dawei.li@shingroup.cn,
rppt@kernel.org, willy@infradead.org, usama.anjum@collabora.com,
osalvador@suse.de, ryan.roberts@arm.com, andrii@kernel.org,
alx@kernel.org, catalin.marinas@arm.com, broonie@kernel.org,
revest@chromium.org, bgray@linux.ibm.com, deller@gmx.de,
zev@bewilderbeest.net
Subject: [PATCH v4 19/30] riscv: Implements arch agnostic shadow stack prctls
Date: Thu, 12 Sep 2024 16:16:38 -0700 [thread overview]
Message-ID: <20240912231650.3740732-20-debug@rivosinc.com> (raw)
In-Reply-To: <20240912231650.3740732-1-debug@rivosinc.com>
Implement architecture agnostic prctls() interface for setting and getting
shadow stack status.
prctls implemented are PR_GET_SHADOW_STACK_STATUS,
PR_SET_SHADOW_STACK_STATUS and PR_LOCK_SHADOW_STACK_STATUS.
As part of PR_SET_SHADOW_STACK_STATUS/PR_GET_SHADOW_STACK_STATUS, only
PR_SHADOW_STACK_ENABLE is implemented because RISCV allows each mode to
write to their own shadow stack using `sspush` or `ssamoswap`.
PR_LOCK_SHADOW_STACK_STATUS locks current configuration of shadow stack
enabling.
Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
arch/riscv/include/asm/usercfi.h | 30 ++++++++-
arch/riscv/kernel/process.c | 8 +++
arch/riscv/kernel/usercfi.c | 107 +++++++++++++++++++++++++++++++
3 files changed, 144 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
index a6974307ca6c..6d806fbb283d 100644
--- a/arch/riscv/include/asm/usercfi.h
+++ b/arch/riscv/include/asm/usercfi.h
@@ -7,6 +7,7 @@
#ifndef __ASSEMBLY__
#include <linux/types.h>
+#include <linux/prctl.h>
struct task_struct;
struct kernel_clone_args;
@@ -14,7 +15,8 @@ struct kernel_clone_args;
#ifdef CONFIG_RISCV_USER_CFI
struct cfi_status {
unsigned long ubcfi_en : 1; /* Enable for backward cfi. */
- unsigned long rsvd : ((sizeof(unsigned long)*8) - 1);
+ unsigned long ubcfi_locked : 1;
+ unsigned long rsvd : ((sizeof(unsigned long)*8) - 2);
unsigned long user_shdw_stk; /* Current user shadow stack pointer */
unsigned long shdw_stk_base; /* Base address of shadow stack */
unsigned long shdw_stk_size; /* size of shadow stack */
@@ -27,6 +29,12 @@ void set_shstk_base(struct task_struct *task, unsigned long shstk_addr, unsigned
unsigned long get_shstk_base(struct task_struct *task, unsigned long *size);
void set_active_shstk(struct task_struct *task, unsigned long shstk_addr);
bool is_shstk_enabled(struct task_struct *task);
+bool is_shstk_locked(struct task_struct *task);
+bool is_shstk_allocated(struct task_struct *task);
+void set_shstk_lock(struct task_struct *task);
+void set_shstk_status(struct task_struct *task, bool enable);
+
+#define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK (PR_SHADOW_STACK_ENABLE)
#else
@@ -62,6 +70,26 @@ static inline bool is_shstk_enabled(struct task_struct *task)
return false;
}
+static inline bool is_shstk_locked(struct task_struct *task)
+{
+ return false;
+}
+
+bool is_shstk_allocated(struct task_struct *task)
+{
+ return false;
+}
+
+void set_shstk_lock(struct task_struct *task)
+{
+
+}
+
+static inline void set_shstk_status(struct task_struct *task, bool enable)
+{
+
+}
+
#endif /* CONFIG_RISCV_USER_CFI */
#endif /* __ASSEMBLY__ */
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 6747db72435a..b64baa0235ea 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -143,6 +143,14 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
regs->epc = pc;
regs->sp = sp;
+ /*
+ * clear shadow stack state on exec.
+ * libc will set it later via prctl.
+ */
+ set_shstk_status(current, false);
+ set_shstk_base(current, 0, 0);
+ set_active_shstk(current, 0);
+
#ifdef CONFIG_64BIT
regs->status &= ~SR_UXL;
diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
index 7a7f0b57b2d4..c77abe552c88 100644
--- a/arch/riscv/kernel/usercfi.c
+++ b/arch/riscv/kernel/usercfi.c
@@ -24,6 +24,16 @@ bool is_shstk_enabled(struct task_struct *task)
return task->thread_info.user_cfi_state.ubcfi_en ? true : false;
}
+bool is_shstk_allocated(struct task_struct *task)
+{
+ return task->thread_info.user_cfi_state.shdw_stk_base ? true : false;
+}
+
+bool is_shstk_locked(struct task_struct *task)
+{
+ return task->thread_info.user_cfi_state.ubcfi_locked ? true : false;
+}
+
void set_shstk_base(struct task_struct *task, unsigned long shstk_addr, unsigned long size)
{
task->thread_info.user_cfi_state.shdw_stk_base = shstk_addr;
@@ -42,6 +52,23 @@ void set_active_shstk(struct task_struct *task, unsigned long shstk_addr)
task->thread_info.user_cfi_state.user_shdw_stk = shstk_addr;
}
+void set_shstk_status(struct task_struct *task, bool enable)
+{
+ task->thread_info.user_cfi_state.ubcfi_en = enable ? 1 : 0;
+
+ if (enable)
+ task->thread_info.envcfg |= ENVCFG_SSE;
+ else
+ task->thread_info.envcfg &= ~ENVCFG_SSE;
+
+ csr_write(CSR_ENVCFG, task->thread_info.envcfg);
+}
+
+void set_shstk_lock(struct task_struct *task)
+{
+ task->thread_info.user_cfi_state.ubcfi_locked = 1;
+}
+
/*
* If size is 0, then to be compatible with regular stack we want it to be as big as
* regular stack. Else PAGE_ALIGN it and return back
@@ -264,3 +291,83 @@ void shstk_release(struct task_struct *tsk)
vm_munmap(base, size);
set_shstk_base(tsk, 0, 0);
}
+
+int arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *status)
+{
+ unsigned long bcfi_status = 0;
+
+ if (!cpu_supports_shadow_stack())
+ return -EINVAL;
+
+ /* this means shadow stack is enabled on the task */
+ bcfi_status |= (is_shstk_enabled(t) ? PR_SHADOW_STACK_ENABLE : 0);
+
+ return copy_to_user(status, &bcfi_status, sizeof(bcfi_status)) ? -EFAULT : 0;
+}
+
+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())
+ return -EINVAL;
+
+ /* Reject unknown flags */
+ if (status & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK)
+ return -EINVAL;
+
+ /* bcfi status is locked and further can't be modified by user */
+ if (is_shstk_locked(t))
+ return -EINVAL;
+
+ enable_shstk = status & PR_SHADOW_STACK_ENABLE;
+ /* Request is to enable shadow stack and shadow stack is not enabled already */
+ if (enable_shstk && !is_shstk_enabled(t)) {
+ /* shadow stack was allocated and enable request again
+ * no need to support such usecase and return EINVAL.
+ */
+ if (is_shstk_allocated(t))
+ return -EINVAL;
+
+ size = calc_shstk_size(0);
+ addr = allocate_shadow_stack(0, size, 0, false);
+ if (IS_ERR_VALUE(addr))
+ return -ENOMEM;
+ set_shstk_base(t, addr, size);
+ set_active_shstk(t, addr + size);
+ }
+
+ /*
+ * If a request to disable shadow stack happens, let's go ahead and release it
+ * Although, if CLONE_VFORKed child did this, then in that case we will end up
+ * not releasing the shadow stack (because it might be needed in parent). Although
+ * we will disable it for VFORKed child. And if VFORKed child tries to enable again
+ * then in that case, it'll get entirely new shadow stack because following condition
+ * are true
+ * - shadow stack was not enabled for vforked child
+ * - shadow stack base was anyways pointing to 0
+ * This shouldn't be a big issue because we want parent to have availability of shadow
+ * stack whenever VFORKed child releases resources via exit or exec but at the same
+ * time we want VFORKed child to break away and establish new shadow stack if it desires
+ *
+ */
+ if (!enable_shstk)
+ shstk_release(t);
+
+ set_shstk_status(t, enable_shstk);
+ return 0;
+}
+
+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() ||
+ !is_shstk_enabled(task))
+ return -EINVAL;
+
+ set_shstk_lock(task);
+
+ return 0;
+}
--
2.45.0
next prev parent reply other threads:[~2024-09-12 23:18 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-12 23:16 [PATCH v4 00/30] riscv control-flow integrity for usermode Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 01/30] mm: Introduce ARCH_HAS_USER_SHADOW_STACK Deepak Gupta
2024-09-13 15:51 ` Carlos Bilbao
2024-09-12 23:16 ` [PATCH v4 02/30] mm: helper `is_shadow_stack_vma` to check shadow stack vma Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 03/30] riscv: Enable cbo.zero only when all harts support Zicboz Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 04/30] riscv: Add support for per-thread envcfg CSR values Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 05/30] riscv: Call riscv_user_isa_enable() only on the boot hart Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 06/30] riscv/Kconfig: enable HAVE_EXIT_THREAD for riscv Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 07/30] riscv: zicfilp / zicfiss in dt-bindings (extensions.yaml) Deepak Gupta
2024-09-13 0:18 ` Rob Herring (Arm)
2024-09-13 18:33 ` Conor Dooley
2024-09-12 23:16 ` [PATCH v4 08/30] riscv: zicfiss / zicfilp enumeration Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 09/30] riscv: zicfiss / zicfilp extension csr and bit definitions Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 10/30] riscv: usercfi state for task and save/restore of CSR_SSP on trap entry/exit Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 11/30] riscv/mm : ensure PROT_WRITE leads to VM_READ | VM_WRITE Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 12/30] riscv mm: manufacture shadow stack pte Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 13/30] riscv mmu: teach pte_mkwrite to manufacture shadow stack PTEs Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 14/30] riscv mmu: write protect and shadow stack Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 15/30] riscv/mm: Implement map_shadow_stack() syscall Deepak Gupta
2024-09-13 15:26 ` Mark Brown
2024-09-12 23:16 ` [PATCH v4 16/30] riscv/shstk: If needed allocate a new shadow stack on clone Deepak Gupta
2024-09-14 1:54 ` kernel test robot
2024-09-14 3:06 ` kernel test robot
2024-09-14 3:26 ` kernel test robot
2024-09-12 23:16 ` [PATCH v4 17/30] prctl: arch-agnostic prctl for shadow stack Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 18/30] prctl: arch-agnostic prctl for indirect branch tracking Deepak Gupta
2024-09-12 23:16 ` Deepak Gupta [this message]
2024-09-12 23:16 ` [PATCH v4 20/30] riscv: Implements arch agnostic indirect branch tracking prctls Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 21/30] riscv/traps: Introduce software check exception Deepak Gupta
2024-09-13 19:35 ` Andy Chiu
2024-09-17 0:00 ` Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 22/30] riscv sigcontext: cfi state struct definition for sigcontext Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 23/30] riscv signal: save and restore of shadow stack for signal Deepak Gupta
2024-09-13 19:25 ` Andy Chiu
2024-09-16 22:03 ` Deepak Gupta
2024-09-17 22:03 ` Andy Chiu
2024-09-17 22:52 ` Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 24/30] riscv/kernel: update __show_regs to print shadow stack register Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 25/30] riscv/ptrace: riscv cfi status and state via ptrace and in core files Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 26/30] riscv/hwprobe: zicfilp / zicfiss enumeration in hwprobe Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 27/30] riscv: create a config for shadow stack and landing pad instr support Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 28/30] riscv: Documentation for landing pad / indirect branch tracking Deepak Gupta
2024-09-16 2:41 ` Bagas Sanjaya
2024-09-12 23:16 ` [PATCH v4 29/30] riscv: Documentation for shadow stack on riscv Deepak Gupta
2024-09-16 3:20 ` Bagas Sanjaya
2024-09-12 23:16 ` [PATCH v4 30/30] kselftest/riscv: kselftest for user mode cfi 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=20240912231650.3740732-20-debug@rivosinc.com \
--to=debug@rivosinc.com \
--cc=Liam.Howlett@oracle.com \
--cc=ajones@ventanamicro.com \
--cc=akpm@linux-foundation.org \
--cc=alexghiti@rivosinc.com \
--cc=alx@kernel.org \
--cc=ancientmodern4@gmail.com \
--cc=andrii@kernel.org \
--cc=andy.chiu@sifive.com \
--cc=antonb@tenstorrent.com \
--cc=anup@brainfault.org \
--cc=aou@eecs.berkeley.edu \
--cc=arnd@arndb.de \
--cc=atishp@rivosinc.com \
--cc=ben.dooks@codethink.co.uk \
--cc=bgray@linux.ibm.com \
--cc=bhe@redhat.com \
--cc=bjorn@rivosinc.com \
--cc=bp@alien8.de \
--cc=brauner@kernel.org \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=charlie@rivosinc.com \
--cc=cleger@rivosinc.com \
--cc=conor@kernel.org \
--cc=corbet@lwn.net \
--cc=costa.shul@redhat.com \
--cc=cuiyunhui@bytedance.com \
--cc=dave.hansen@linux.intel.com \
--cc=david@redhat.com \
--cc=dawei.li@shingroup.cn \
--cc=deller@gmx.de \
--cc=devicetree@vger.kernel.org \
--cc=ebiederm@xmission.com \
--cc=evan@rivosinc.com \
--cc=greentime.hu@sifive.com \
--cc=guoren@kernel.org \
--cc=hpa@zytor.com \
--cc=jerry.shih@sifive.com \
--cc=jszhang@kernel.org \
--cc=ke.zhao@shingroup.cn \
--cc=kees@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=leobras@redhat.com \
--cc=libang.li@antgroup.com \
--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=mchitale@ventanamicro.com \
--cc=mingo@redhat.com \
--cc=namcaov@gmail.com \
--cc=oleg@redhat.com \
--cc=osalvador@suse.de \
--cc=palmer@dabbelt.com \
--cc=palmer@sifive.com \
--cc=paul.walmsley@sifive.com \
--cc=peterz@infradead.org \
--cc=puranjay@kernel.org \
--cc=quic_bjorande@quicinc.com \
--cc=quic_zhonhan@quicinc.com \
--cc=revest@chromium.org \
--cc=robh@kernel.org \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=sameo@rivosinc.com \
--cc=samitolvanen@google.com \
--cc=samuel.holland@sifive.com \
--cc=schwab@suse.de \
--cc=shuah@kernel.org \
--cc=songshuaishuai@tinylab.org \
--cc=sorear@fastmail.com \
--cc=sunilvl@ventanamicro.com \
--cc=tanzhasanwork@gmail.com \
--cc=tglx@linutronix.de \
--cc=usama.anjum@collabora.com \
--cc=vbabka@suse.cz \
--cc=willy@infradead.org \
--cc=x86@kernel.org \
--cc=xiao.w.wang@intel.com \
--cc=yang.lee@linux.alibaba.com \
--cc=zev@bewilderbeest.net \
--cc=zong.li@sifive.com \
/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).