All of lore.kernel.org
 help / color / mirror / Atom feed
From: Deepak Gupta <debug@rivosinc.com>
To: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>
Cc: Deepak Gupta <debug@rivosinc.com>
Subject: [PATCH v1 RFC Zisslpcfi 04/20] riscv: kernel enabling user code for shadow stack and landing pad
Date: Sun, 12 Feb 2023 20:53:33 -0800	[thread overview]
Message-ID: <20230213045351.3945824-5-debug@rivosinc.com> (raw)
In-Reply-To: <20230213045351.3945824-1-debug@rivosinc.com>

Enables architectural support for shadow stack and landing pad instr
for user mode on riscv.

This patch does following
- Defines a new structure cfi_status
- Includes cfi_status in thread_info
- Defines offsets to new member fields in thread_info in asm-offsets.c
- Saves and restore cfi state on trap entry (U --> S) and exit (S --> U)

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
 arch/riscv/include/asm/processor.h   | 11 ++++++++
 arch/riscv/include/asm/thread_info.h |  5 ++++
 arch/riscv/kernel/asm-offsets.c      |  5 ++++
 arch/riscv/kernel/entry.S            | 40 ++++++++++++++++++++++++++++
 4 files changed, 61 insertions(+)

diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index bdebce2cc323..f065309927b1 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -41,6 +41,17 @@ struct thread_struct {
 	unsigned long bad_cause;
 };
 
+#if defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+struct cfi_status {
+	unsigned int ufcfi_en : 1; /* Enable for forward cfi. Note that ELP goes in sstatus */
+	unsigned int ubcfi_en : 1; /* Enable for backward cfi. */
+	unsigned int rsvd1 : 30;
+	unsigned int lp_label; /* saved label value (25bit) */
+	long user_shdw_stk; /* Current user shadow stack pointer */
+	long shdw_stk_base; /* Base address of shadow stack */
+};
+#endif
+
 /* Whitelist the fstate from the task_struct for hardened usercopy */
 static inline void arch_thread_struct_whitelist(unsigned long *offset,
 						unsigned long *size)
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 67322f878e0d..f74b8bd55d5b 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -65,6 +65,11 @@ struct thread_info {
 	 */
 	long			kernel_sp;	/* Kernel stack pointer */
 	long			user_sp;	/* User stack pointer */
+#if defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+	/* cfi_state only if config is defined */
+	/* state of user cfi state. note this includes LPLR and SSP as well */
+	struct cfi_status       user_cfi_state;
+#endif
 	int			cpu;
 };
 
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index df9444397908..340e6413cf3c 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -38,6 +38,11 @@ void asm_offsets(void)
 	OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp);
 	OFFSET(TASK_TI_USER_SP, task_struct, thread_info.user_sp);
 
+#if defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+	OFFSET(TASK_TI_USER_CFI_STATUS, task_struct, thread_info.user_cfi_state);
+	OFFSET(TASK_TI_USER_LPLR, task_struct, thread_info.user_cfi_state.lp_label);
+	OFFSET(TASK_TI_USER_SSP, task_struct, thread_info.user_cfi_state.user_shdw_stk);
+#endif
 	OFFSET(TASK_THREAD_F0,  task_struct, thread.fstate.f[0]);
 	OFFSET(TASK_THREAD_F1,  task_struct, thread.fstate.f[1]);
 	OFFSET(TASK_THREAD_F2,  task_struct, thread.fstate.f[2]);
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 99d38fdf8b18..f283130c81ec 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -73,6 +73,31 @@ _save_context:
 	REG_S x30, PT_T5(sp)
 	REG_S x31, PT_T6(sp)
 
+#if	defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+	/*
+	* If U --> S, CSR_SCRATCH should be holding U TP
+	* If S --> S, CSR_SCRATCH should be holding S TP
+	* s2 == tp means, previous mode was S
+	* else previous mode U
+	* we need to save cfi status only when previous mode was U
+	*/
+	csrr s2, CSR_SCRATCH
+	xor s2, s2, tp
+	beqz s2, skip_bcfi_save
+	/* load cfi status word */
+	lw s2, TASK_TI_USER_CFI_STATUS(tp)
+	andi s3, s2, 1
+	beqz s3, skip_fcfi_save
+	/* fcfi is enabled, capture ELP and LPLR state and record it */
+	csrr s3, CSR_LPLR /* record label register */
+	sw s3, TASK_TI_USER_LPLR(tp) /* save it back in thread_info structure */
+skip_fcfi_save:
+	andi s3, s2, 2
+	beqz s3, skip_bcfi_save
+	csrr s3, CSR_SSP
+	REG_S s3, TASK_TI_USER_SSP(tp) /* save user ssp in thread_info */
+skip_bcfi_save:
+#endif
 	/*
 	 * Disable user-mode memory access as it should only be set in the
 	 * actual user copy routines.
@@ -283,6 +308,21 @@ resume_userspace:
 	 */
 	csrw CSR_SCRATCH, tp
 
+#if	defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+	lw s2, TASK_TI_USER_CFI_STATUS(tp)
+	andi s3, s2, 1
+	beqz s3, skip_fcfi_resume
+	xor s3, s3, s3
+	lw s3, TASK_TI_USER_LPLR(tp)
+	csrw CSR_LPLR, s3
+skip_fcfi_resume:
+	andi s3, s2, 2
+	beqz s3, skip_bcfi_resume
+	REG_L s3, TASK_TI_USER_SSP(tp) /* save user ssp in thread_info */
+	csrw CSR_SSP, s3
+skip_bcfi_resume:
+#endif
+
 restore_all:
 #ifdef CONFIG_TRACE_IRQFLAGS
 	REG_L s1, PT_STATUS(sp)
-- 
2.25.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

WARNING: multiple messages have this Message-ID (diff)
From: Deepak Gupta <debug@rivosinc.com>
To: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>
Cc: Deepak Gupta <debug@rivosinc.com>
Subject: [PATCH v1 RFC Zisslpcfi 04/20] riscv: kernel enabling user code for shadow stack and landing pad
Date: Sun, 12 Feb 2023 20:53:33 -0800	[thread overview]
Message-ID: <20230213045351.3945824-5-debug@rivosinc.com> (raw)
In-Reply-To: <20230213045351.3945824-1-debug@rivosinc.com>

Enables architectural support for shadow stack and landing pad instr
for user mode on riscv.

This patch does following
- Defines a new structure cfi_status
- Includes cfi_status in thread_info
- Defines offsets to new member fields in thread_info in asm-offsets.c
- Saves and restore cfi state on trap entry (U --> S) and exit (S --> U)

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
 arch/riscv/include/asm/processor.h   | 11 ++++++++
 arch/riscv/include/asm/thread_info.h |  5 ++++
 arch/riscv/kernel/asm-offsets.c      |  5 ++++
 arch/riscv/kernel/entry.S            | 40 ++++++++++++++++++++++++++++
 4 files changed, 61 insertions(+)

diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index bdebce2cc323..f065309927b1 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -41,6 +41,17 @@ struct thread_struct {
 	unsigned long bad_cause;
 };
 
+#if defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+struct cfi_status {
+	unsigned int ufcfi_en : 1; /* Enable for forward cfi. Note that ELP goes in sstatus */
+	unsigned int ubcfi_en : 1; /* Enable for backward cfi. */
+	unsigned int rsvd1 : 30;
+	unsigned int lp_label; /* saved label value (25bit) */
+	long user_shdw_stk; /* Current user shadow stack pointer */
+	long shdw_stk_base; /* Base address of shadow stack */
+};
+#endif
+
 /* Whitelist the fstate from the task_struct for hardened usercopy */
 static inline void arch_thread_struct_whitelist(unsigned long *offset,
 						unsigned long *size)
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 67322f878e0d..f74b8bd55d5b 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -65,6 +65,11 @@ struct thread_info {
 	 */
 	long			kernel_sp;	/* Kernel stack pointer */
 	long			user_sp;	/* User stack pointer */
+#if defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+	/* cfi_state only if config is defined */
+	/* state of user cfi state. note this includes LPLR and SSP as well */
+	struct cfi_status       user_cfi_state;
+#endif
 	int			cpu;
 };
 
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index df9444397908..340e6413cf3c 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -38,6 +38,11 @@ void asm_offsets(void)
 	OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp);
 	OFFSET(TASK_TI_USER_SP, task_struct, thread_info.user_sp);
 
+#if defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+	OFFSET(TASK_TI_USER_CFI_STATUS, task_struct, thread_info.user_cfi_state);
+	OFFSET(TASK_TI_USER_LPLR, task_struct, thread_info.user_cfi_state.lp_label);
+	OFFSET(TASK_TI_USER_SSP, task_struct, thread_info.user_cfi_state.user_shdw_stk);
+#endif
 	OFFSET(TASK_THREAD_F0,  task_struct, thread.fstate.f[0]);
 	OFFSET(TASK_THREAD_F1,  task_struct, thread.fstate.f[1]);
 	OFFSET(TASK_THREAD_F2,  task_struct, thread.fstate.f[2]);
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 99d38fdf8b18..f283130c81ec 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -73,6 +73,31 @@ _save_context:
 	REG_S x30, PT_T5(sp)
 	REG_S x31, PT_T6(sp)
 
+#if	defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+	/*
+	* If U --> S, CSR_SCRATCH should be holding U TP
+	* If S --> S, CSR_SCRATCH should be holding S TP
+	* s2 == tp means, previous mode was S
+	* else previous mode U
+	* we need to save cfi status only when previous mode was U
+	*/
+	csrr s2, CSR_SCRATCH
+	xor s2, s2, tp
+	beqz s2, skip_bcfi_save
+	/* load cfi status word */
+	lw s2, TASK_TI_USER_CFI_STATUS(tp)
+	andi s3, s2, 1
+	beqz s3, skip_fcfi_save
+	/* fcfi is enabled, capture ELP and LPLR state and record it */
+	csrr s3, CSR_LPLR /* record label register */
+	sw s3, TASK_TI_USER_LPLR(tp) /* save it back in thread_info structure */
+skip_fcfi_save:
+	andi s3, s2, 2
+	beqz s3, skip_bcfi_save
+	csrr s3, CSR_SSP
+	REG_S s3, TASK_TI_USER_SSP(tp) /* save user ssp in thread_info */
+skip_bcfi_save:
+#endif
 	/*
 	 * Disable user-mode memory access as it should only be set in the
 	 * actual user copy routines.
@@ -283,6 +308,21 @@ resume_userspace:
 	 */
 	csrw CSR_SCRATCH, tp
 
+#if	defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+	lw s2, TASK_TI_USER_CFI_STATUS(tp)
+	andi s3, s2, 1
+	beqz s3, skip_fcfi_resume
+	xor s3, s3, s3
+	lw s3, TASK_TI_USER_LPLR(tp)
+	csrw CSR_LPLR, s3
+skip_fcfi_resume:
+	andi s3, s2, 2
+	beqz s3, skip_bcfi_resume
+	REG_L s3, TASK_TI_USER_SSP(tp) /* save user ssp in thread_info */
+	csrw CSR_SSP, s3
+skip_bcfi_resume:
+#endif
+
 restore_all:
 #ifdef CONFIG_TRACE_IRQFLAGS
 	REG_L s1, PT_STATUS(sp)
-- 
2.25.1


  parent reply	other threads:[~2023-02-13  4:54 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-13  4:53 [PATCH v1 RFC Zisslpcfi 00/20] riscv control-flow integrity for U mode Deepak Gupta
2023-02-13  4:53 ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 01/20] sslp stubs: shadow stack and landing pad stubs Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 02/20] riscv: zisslpcfi enumeration Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 03/20] riscv: zisslpcfi extension csr and bit definitions Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` Deepak Gupta [this message]
2023-02-13  4:53   ` [PATCH v1 RFC Zisslpcfi 04/20] riscv: kernel enabling user code for shadow stack and landing pad Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 05/20] mmap : Introducing new protection "PROT_SHADOWSTACK" for mmap Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  7:10   ` kernel test robot
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 06/20] riscv: Implementing "PROT_SHADOWSTACK" on riscv Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 07/20] elf: ELF header parsing in GNU property for cfi state Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 08/20] riscv: ELF header parsing in GNU property for riscv zisslpcfi Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  7:10   ` kernel test robot
2023-02-13  8:57   ` kernel test robot
2023-02-13 18:34   ` kernel test robot
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 09/20] riscv mmu: riscv shadow stack page fault handling Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13 19:36   ` kernel test robot
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 10/20] riscv mmu: write protect and shadow stack Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 11/20] mmu: maybe_mkwrite updated to manufacture shadow stack PTEs Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13 12:05   ` David Hildenbrand
2023-02-13 12:05     ` David Hildenbrand
2023-02-13 14:37     ` Deepak Gupta
2023-02-13 14:37       ` Deepak Gupta
2023-02-13 14:56       ` David Hildenbrand
2023-02-13 14:56         ` David Hildenbrand
2023-02-13 20:01         ` Deepak Gupta
2023-02-13 20:01           ` Deepak Gupta
2023-02-14 12:10           ` David Hildenbrand
2023-02-14 12:10             ` David Hildenbrand
2023-02-14 18:27             ` Edgecombe, Rick P
2023-02-14 18:27               ` Edgecombe, Rick P
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 12/20] riscv mm: manufacture shadow stack pte and is vma shadowstack Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 13/20] riscv: illegal instruction handler for cfi violations Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 14/20] riscv: audit mode " Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 15/20] sslp prctl: arch-agnostic prctl for shadow stack and landing pad instr Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  7:31   ` kernel test robot
2023-05-25 17:17   ` Mark Brown
2023-05-25 17:17     ` Mark Brown
2023-06-07 20:22   ` Mark Brown
2023-06-07 20:22     ` Mark Brown
2023-10-09 21:22     ` Deepak Gupta
2023-10-09 21:22       ` Deepak Gupta
2023-10-10 16:17       ` Mark Brown
2023-10-10 16:17         ` Mark Brown
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 16/20] riscv: Implements sslp prctls Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 17/20] riscv ucontext: adding shadow stack pointer field in ucontext Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 18/20] riscv signal: Save and restore of shadow stack for signal Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 19/20] config: adding two new config for control flow integrity Deepak Gupta
2023-02-13  4:53   ` Deepak Gupta
2023-02-13  4:53 ` [PATCH v1 RFC Zisslpcfi 20/20] riscv: select config for shadow stack and landing pad instr support Deepak Gupta
2023-02-13  4:53   ` 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=20230213045351.3945824-5-debug@rivosinc.com \
    --to=debug@rivosinc.com \
    --cc=aou@eecs.berkeley.edu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.