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 13/20] riscv: illegal instruction handler for cfi violations
Date: Sun, 12 Feb 2023 20:53:42 -0800	[thread overview]
Message-ID: <20230213045351.3945824-14-debug@rivosinc.com> (raw)
In-Reply-To: <20230213045351.3945824-1-debug@rivosinc.com>

Zisslpcfi spec proposes that cfi violations are reported as illegal
instruction exception. Following are the cases

- elp missing: An indirect jmp/call landed on instruction which is
  not `lpcll`
- label mismatch: Static label embedded in instr `lpcll/lpcml/lpcul`
  doesn't match with repsective label in CSR_LPLR
- sscheckra: x1 and x5 don't match.

Current changes run user code in audit mode. That means that any cfi
violation is suppressed and app is allowed to continue.

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
 arch/riscv/kernel/traps.c | 79 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 5553b8d48ba5..a292699f4f25 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -97,6 +97,10 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
 /* Zisslpcfi instructions encodings */
 #define SS_PUSH_POP 0x81C04073
 #define SS_AMOSWAP  0x82004073
+#define SS_CHECKRA  0x8A12C073
+#define LP_C_LL     0x83004073
+#define LP_C_ML     0x86804073
+#define LP_C_UL     0x8B804073
 
 bool is_ss_load_store_insn(unsigned long insn)
 {
@@ -112,6 +116,71 @@ bool is_ss_load_store_insn(unsigned long insn)
 	return false;
 }
 
+bool is_cfi_violation_insn(unsigned long insn)
+{
+	struct task_struct *task = current;
+	bool ss_exist = false, lp_exist = false;
+
+	ss_exist = arch_supports_shadow_stack();
+	lp_exist = arch_supports_indirect_br_lp_instr();
+
+	if (ss_exist && (insn == SS_CHECKRA)) {
+		pr_warn("cfi violation (sschkra): comm = %s, task = %p\n", task->comm, task);
+		return true;
+	}
+	if (lp_exist && ((insn & LP_C_LL) == LP_C_LL)) {
+		pr_warn("cfi violation (lpcll): comm = %s, task = %p\n", task->comm, task);
+		return true;
+	}
+	if (lp_exist && ((insn & LP_C_ML) == LP_C_ML)) {
+		pr_warn("cfi violation (lpcml): comm = %s, task = %p\n", task->comm, task);
+		return true;
+	}
+	if (lp_exist && ((insn & LP_C_UL) == LP_C_UL)) {
+		pr_warn("cfi violation (lpcul): comm = %s, task = %p\n", task->comm, task);
+		return true;
+	}
+
+	return false;
+}
+
+int handle_illegal_instruction(struct pt_regs *regs)
+{
+	/* stval should hold faulting opcode */
+	unsigned long insn = csr_read(stval);
+	struct thread_info *info = NULL;
+	struct task_struct *task = current;
+
+	info = current_thread_info();
+	/*
+	 * If CFI enabled then following instructions leads to illegal instruction fault
+	 * -- sscheckra: x1 and x5 mismatch
+	 * -- ELP = 1, Any instruction other than lpcll will fault
+	 * -- lpcll will fault if lower label don't match with LPLR.LL
+	 * -- lpcml will fault if lower label don't match with LPLR.ML
+	 * -- lpcul will fault if lower label don't match with LPLR.UL
+	 */
+
+	/* If fcfi enabled and  ELP = 1, suppress ELP (audit mode)  and resume */
+	if (arch_supports_indirect_br_lp_instr() &&
+#ifdef CONFIG_USER_INDIRECT_BR_LP
+	    info->user_cfi_state.ufcfi_en &&
+#endif
+	    (regs->status & SR_ELP)) {
+		pr_warn("cfi violation (elp): comm = %s, task = %p\n", task->comm, task);
+		regs->status &= ~(SR_ELP);
+		return 0;
+	}
+	/* if faulting opcode is sscheckra/lpcll/lpcml/lpcll, advance PC and resume */
+	if (is_cfi_violation_insn(insn)) {
+		/* no compressed form for zisslpcfi instructions */
+		regs->epc += 4;
+		return 0;
+	}
+
+	return 1;
+}
+
 ulong get_instruction(ulong epc)
 {
 	ulong *epc_ptr = (ulong *) epc;
@@ -190,8 +259,14 @@ DO_ERROR_INFO(do_trap_insn_misaligned,
 	SIGBUS, BUS_ADRALN, "instruction address misaligned");
 DO_ERROR_INFO(do_trap_insn_fault,
 	SIGSEGV, SEGV_ACCERR, "instruction access fault");
-DO_ERROR_INFO(do_trap_insn_illegal,
-	SIGILL, ILL_ILLOPC, "illegal instruction");
+
+asmlinkage void __trap_section do_trap_insn_illegal(struct pt_regs *regs)
+{
+	if (!handle_illegal_instruction(regs))
+		return;
+	do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->epc,
+		      "illegal instruction");
+}
 #ifdef CONFIG_USER_SHADOW_STACK
 asmlinkage void __trap_section do_trap_load_fault(struct pt_regs *regs)
 {
-- 
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 13/20] riscv: illegal instruction handler for cfi violations
Date: Sun, 12 Feb 2023 20:53:42 -0800	[thread overview]
Message-ID: <20230213045351.3945824-14-debug@rivosinc.com> (raw)
In-Reply-To: <20230213045351.3945824-1-debug@rivosinc.com>

Zisslpcfi spec proposes that cfi violations are reported as illegal
instruction exception. Following are the cases

- elp missing: An indirect jmp/call landed on instruction which is
  not `lpcll`
- label mismatch: Static label embedded in instr `lpcll/lpcml/lpcul`
  doesn't match with repsective label in CSR_LPLR
- sscheckra: x1 and x5 don't match.

Current changes run user code in audit mode. That means that any cfi
violation is suppressed and app is allowed to continue.

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
 arch/riscv/kernel/traps.c | 79 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 5553b8d48ba5..a292699f4f25 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -97,6 +97,10 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
 /* Zisslpcfi instructions encodings */
 #define SS_PUSH_POP 0x81C04073
 #define SS_AMOSWAP  0x82004073
+#define SS_CHECKRA  0x8A12C073
+#define LP_C_LL     0x83004073
+#define LP_C_ML     0x86804073
+#define LP_C_UL     0x8B804073
 
 bool is_ss_load_store_insn(unsigned long insn)
 {
@@ -112,6 +116,71 @@ bool is_ss_load_store_insn(unsigned long insn)
 	return false;
 }
 
+bool is_cfi_violation_insn(unsigned long insn)
+{
+	struct task_struct *task = current;
+	bool ss_exist = false, lp_exist = false;
+
+	ss_exist = arch_supports_shadow_stack();
+	lp_exist = arch_supports_indirect_br_lp_instr();
+
+	if (ss_exist && (insn == SS_CHECKRA)) {
+		pr_warn("cfi violation (sschkra): comm = %s, task = %p\n", task->comm, task);
+		return true;
+	}
+	if (lp_exist && ((insn & LP_C_LL) == LP_C_LL)) {
+		pr_warn("cfi violation (lpcll): comm = %s, task = %p\n", task->comm, task);
+		return true;
+	}
+	if (lp_exist && ((insn & LP_C_ML) == LP_C_ML)) {
+		pr_warn("cfi violation (lpcml): comm = %s, task = %p\n", task->comm, task);
+		return true;
+	}
+	if (lp_exist && ((insn & LP_C_UL) == LP_C_UL)) {
+		pr_warn("cfi violation (lpcul): comm = %s, task = %p\n", task->comm, task);
+		return true;
+	}
+
+	return false;
+}
+
+int handle_illegal_instruction(struct pt_regs *regs)
+{
+	/* stval should hold faulting opcode */
+	unsigned long insn = csr_read(stval);
+	struct thread_info *info = NULL;
+	struct task_struct *task = current;
+
+	info = current_thread_info();
+	/*
+	 * If CFI enabled then following instructions leads to illegal instruction fault
+	 * -- sscheckra: x1 and x5 mismatch
+	 * -- ELP = 1, Any instruction other than lpcll will fault
+	 * -- lpcll will fault if lower label don't match with LPLR.LL
+	 * -- lpcml will fault if lower label don't match with LPLR.ML
+	 * -- lpcul will fault if lower label don't match with LPLR.UL
+	 */
+
+	/* If fcfi enabled and  ELP = 1, suppress ELP (audit mode)  and resume */
+	if (arch_supports_indirect_br_lp_instr() &&
+#ifdef CONFIG_USER_INDIRECT_BR_LP
+	    info->user_cfi_state.ufcfi_en &&
+#endif
+	    (regs->status & SR_ELP)) {
+		pr_warn("cfi violation (elp): comm = %s, task = %p\n", task->comm, task);
+		regs->status &= ~(SR_ELP);
+		return 0;
+	}
+	/* if faulting opcode is sscheckra/lpcll/lpcml/lpcll, advance PC and resume */
+	if (is_cfi_violation_insn(insn)) {
+		/* no compressed form for zisslpcfi instructions */
+		regs->epc += 4;
+		return 0;
+	}
+
+	return 1;
+}
+
 ulong get_instruction(ulong epc)
 {
 	ulong *epc_ptr = (ulong *) epc;
@@ -190,8 +259,14 @@ DO_ERROR_INFO(do_trap_insn_misaligned,
 	SIGBUS, BUS_ADRALN, "instruction address misaligned");
 DO_ERROR_INFO(do_trap_insn_fault,
 	SIGSEGV, SEGV_ACCERR, "instruction access fault");
-DO_ERROR_INFO(do_trap_insn_illegal,
-	SIGILL, ILL_ILLOPC, "illegal instruction");
+
+asmlinkage void __trap_section do_trap_insn_illegal(struct pt_regs *regs)
+{
+	if (!handle_illegal_instruction(regs))
+		return;
+	do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->epc,
+		      "illegal instruction");
+}
 #ifdef CONFIG_USER_SHADOW_STACK
 asmlinkage void __trap_section do_trap_load_fault(struct pt_regs *regs)
 {
-- 
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 ` [PATCH v1 RFC Zisslpcfi 04/20] riscv: kernel enabling user code for shadow stack and landing pad Deepak Gupta
2023-02-13  4:53   ` 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 ` Deepak Gupta [this message]
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 ` [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-14-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.