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>,
Eric Biederman <ebiederm@xmission.com>,
Kees Cook <keescook@chromium.org>
Cc: Deepak Gupta <debug@rivosinc.com>, linux-mm@kvack.org
Subject: [PATCH v1 RFC Zisslpcfi 08/20] riscv: ELF header parsing in GNU property for riscv zisslpcfi
Date: Sun, 12 Feb 2023 20:53:37 -0800 [thread overview]
Message-ID: <20230213045351.3945824-9-debug@rivosinc.com> (raw)
In-Reply-To: <20230213045351.3945824-1-debug@rivosinc.com>
Binaries enabled for Zisslpcfi will have new instructions that may fault
on risc-v cpus which dont implement Zimops or Zicfi. This change adds
- support for parsing new backward and forward cfi flags in
PT_GNU_PROPERTY
- setting cfi state on recognizing cfi flags in ELF
- enable back cfi and forward cfi in sstatus
Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
arch/riscv/include/asm/elf.h | 54 +++++++++++++++++++++++++++++
arch/riscv/kernel/process.c | 67 ++++++++++++++++++++++++++++++++++++
2 files changed, 121 insertions(+)
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index e7acffdf21d2..60ac2d2390ee 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -14,6 +14,7 @@
#include <asm/auxvec.h>
#include <asm/byteorder.h>
#include <asm/cacheinfo.h>
+#include <linux/processor.h>
/*
* These are used to set parameters in the core dumps.
@@ -140,4 +141,57 @@ extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
compat_arch_setup_additional_pages
#endif /* CONFIG_COMPAT */
+
+#define RISCV_ELF_FCFI (1 << 0)
+#define RISCV_ELF_BCFI (1 << 1)
+
+#ifdef CONFIG_ARCH_BINFMT_ELF_STATE
+struct arch_elf_state {
+ int flags;
+};
+
+#define INIT_ARCH_ELF_STATE { \
+ .flags = 0, \
+}
+#endif
+
+#ifdef CONFIG_ARCH_USE_GNU_PROPERTY
+static inline int arch_parse_elf_property(u32 type, const void *data,
+ size_t datasz, bool compat,
+ struct arch_elf_state *arch)
+{
+ /*
+ * TODO: Do we want to support in 32bit/compat?
+ * may be return 0 for now.
+ */
+ if (IS_ENABLED(CONFIG_COMPAT) && compat)
+ return 0;
+ if ((type & GNU_PROPERTY_RISCV_FEATURE_1_AND) == GNU_PROPERTY_RISCV_FEATURE_1_AND) {
+ const u32 *p = data;
+
+ if (datasz != sizeof(*p))
+ return -ENOEXEC;
+ if (arch_supports_indirect_br_lp_instr() &&
+ (*p & GNU_PROPERTY_RISCV_FEATURE_1_FCFI))
+ arch->flags |= RISCV_ELF_FCFI;
+ if (arch_supports_shadow_stack() && (*p & GNU_PROPERTY_RISCV_FEATURE_1_BCFI))
+ arch->flags |= RISCV_ELF_BCFI;
+ }
+ return 0;
+}
+
+static inline int arch_elf_pt_proc(void *ehdr, void *phdr,
+ struct file *f, bool is_interp,
+ struct arch_elf_state *state)
+{
+ return 0;
+}
+
+static inline int arch_check_elf(void *ehdr, bool has_interp,
+ void *interp_ehdr,
+ struct arch_elf_state *state)
+{
+ return 0;
+}
+#endif
#endif /* _ASM_RISCV_ELF_H */
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 8955f2432c2d..db676262e61e 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -24,6 +24,7 @@
#include <asm/switch_to.h>
#include <asm/thread_info.h>
#include <asm/cpuidle.h>
+#include <linux/mman.h>
register unsigned long gp_in_global __asm__("gp");
@@ -135,6 +136,14 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
else
regs->status |= SR_UXL_64;
#endif
+#ifdef CONFIG_USER_SHADOW_STACK
+ if (current_thread_info()->user_cfi_state.ufcfi_en)
+ regs->status |= SR_UFCFIEN;
+#endif
+#ifdef CONFIG_USER_INDIRECT_BR_LP
+ if (current_thread_info()->user_cfi_state.ubcfi_en)
+ regs->status |= SR_UBCFIEN;
+#endif
}
void flush_thread(void)
@@ -189,3 +198,61 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
p->thread.sp = (unsigned long)childregs; /* kernel sp */
return 0;
}
+
+
+int allocate_shadow_stack(unsigned long *shadow_stack_base, unsigned long *shdw_size)
+{
+ int flags = MAP_ANONYMOUS | MAP_PRIVATE;
+ struct mm_struct *mm = current->mm;
+ unsigned long addr, populate, size;
+ *shadow_stack = 0;
+
+ if (!shdw_size)
+ return -EINVAL;
+
+ size = *shdw_size;
+
+ /* If size is 0, then try to calculate yourself */
+ if (size == 0)
+ size = round_up(min_t(unsigned long long, rlimit(RLIMIT_STACK), SZ_4G), PAGE_SIZE);
+ mmap_write_lock(mm);
+ addr = do_mmap(NULL, 0, size, PROT_SHADOWSTACK, flags, 0,
+ &populate, NULL);
+ mmap_write_unlock(mm);
+ if (IS_ERR_VALUE(addr))
+ return PTR_ERR((void *)addr);
+ *shadow_stack_base = addr;
+ *shdw_size = size;
+ return 0;
+}
+
+#if defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+/* gets called from load_elf_binary(). This'll setup shadow stack and forward cfi enable */
+int arch_elf_setup_cfi_state(const struct arch_elf_state *state)
+{
+ int ret = 0;
+ unsigned long shadow_stack_base = 0;
+ unsigned long shadow_stk_size = 0;
+ struct thread_info *info = NULL;
+
+ info = current_thread_info();
+ /* setup back cfi state */
+ /* setup cfi state only if implementation supports it */
+ if (arch_supports_shadow_stack() && (state->flags & RISCV_ELF_BCFI)) {
+ info->user_cfi_state.ubcfi_en = 1;
+ ret = allocate_shadow_stack(&shadow_stack_base, &shadow_stk_size);
+ if (ret)
+ return ret;
+
+ info->user_cfi_state.user_shdw_stk = (shadow_stack_base + shadow_stk_size);
+ info->user_cfi_state.shdw_stk_base = shadow_stack_base;
+ }
+ /* setup forward cfi state */
+ if (arch_supports_indirect_br_lp_instr() && (state->flags & RISCV_ELF_FCFI)) {
+ info->user_cfi_state.ufcfi_en = 1;
+ info->user_cfi_state.lp_label = 0;
+ }
+
+ return ret;
+}
+#endif
\ No newline at end of file
--
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>,
Eric Biederman <ebiederm@xmission.com>,
Kees Cook <keescook@chromium.org>
Cc: Deepak Gupta <debug@rivosinc.com>, linux-mm@kvack.org
Subject: [PATCH v1 RFC Zisslpcfi 08/20] riscv: ELF header parsing in GNU property for riscv zisslpcfi
Date: Sun, 12 Feb 2023 20:53:37 -0800 [thread overview]
Message-ID: <20230213045351.3945824-9-debug@rivosinc.com> (raw)
In-Reply-To: <20230213045351.3945824-1-debug@rivosinc.com>
Binaries enabled for Zisslpcfi will have new instructions that may fault
on risc-v cpus which dont implement Zimops or Zicfi. This change adds
- support for parsing new backward and forward cfi flags in
PT_GNU_PROPERTY
- setting cfi state on recognizing cfi flags in ELF
- enable back cfi and forward cfi in sstatus
Signed-off-by: Deepak Gupta <debug@rivosinc.com>
---
arch/riscv/include/asm/elf.h | 54 +++++++++++++++++++++++++++++
arch/riscv/kernel/process.c | 67 ++++++++++++++++++++++++++++++++++++
2 files changed, 121 insertions(+)
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index e7acffdf21d2..60ac2d2390ee 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -14,6 +14,7 @@
#include <asm/auxvec.h>
#include <asm/byteorder.h>
#include <asm/cacheinfo.h>
+#include <linux/processor.h>
/*
* These are used to set parameters in the core dumps.
@@ -140,4 +141,57 @@ extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
compat_arch_setup_additional_pages
#endif /* CONFIG_COMPAT */
+
+#define RISCV_ELF_FCFI (1 << 0)
+#define RISCV_ELF_BCFI (1 << 1)
+
+#ifdef CONFIG_ARCH_BINFMT_ELF_STATE
+struct arch_elf_state {
+ int flags;
+};
+
+#define INIT_ARCH_ELF_STATE { \
+ .flags = 0, \
+}
+#endif
+
+#ifdef CONFIG_ARCH_USE_GNU_PROPERTY
+static inline int arch_parse_elf_property(u32 type, const void *data,
+ size_t datasz, bool compat,
+ struct arch_elf_state *arch)
+{
+ /*
+ * TODO: Do we want to support in 32bit/compat?
+ * may be return 0 for now.
+ */
+ if (IS_ENABLED(CONFIG_COMPAT) && compat)
+ return 0;
+ if ((type & GNU_PROPERTY_RISCV_FEATURE_1_AND) == GNU_PROPERTY_RISCV_FEATURE_1_AND) {
+ const u32 *p = data;
+
+ if (datasz != sizeof(*p))
+ return -ENOEXEC;
+ if (arch_supports_indirect_br_lp_instr() &&
+ (*p & GNU_PROPERTY_RISCV_FEATURE_1_FCFI))
+ arch->flags |= RISCV_ELF_FCFI;
+ if (arch_supports_shadow_stack() && (*p & GNU_PROPERTY_RISCV_FEATURE_1_BCFI))
+ arch->flags |= RISCV_ELF_BCFI;
+ }
+ return 0;
+}
+
+static inline int arch_elf_pt_proc(void *ehdr, void *phdr,
+ struct file *f, bool is_interp,
+ struct arch_elf_state *state)
+{
+ return 0;
+}
+
+static inline int arch_check_elf(void *ehdr, bool has_interp,
+ void *interp_ehdr,
+ struct arch_elf_state *state)
+{
+ return 0;
+}
+#endif
#endif /* _ASM_RISCV_ELF_H */
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 8955f2432c2d..db676262e61e 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -24,6 +24,7 @@
#include <asm/switch_to.h>
#include <asm/thread_info.h>
#include <asm/cpuidle.h>
+#include <linux/mman.h>
register unsigned long gp_in_global __asm__("gp");
@@ -135,6 +136,14 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
else
regs->status |= SR_UXL_64;
#endif
+#ifdef CONFIG_USER_SHADOW_STACK
+ if (current_thread_info()->user_cfi_state.ufcfi_en)
+ regs->status |= SR_UFCFIEN;
+#endif
+#ifdef CONFIG_USER_INDIRECT_BR_LP
+ if (current_thread_info()->user_cfi_state.ubcfi_en)
+ regs->status |= SR_UBCFIEN;
+#endif
}
void flush_thread(void)
@@ -189,3 +198,61 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
p->thread.sp = (unsigned long)childregs; /* kernel sp */
return 0;
}
+
+
+int allocate_shadow_stack(unsigned long *shadow_stack_base, unsigned long *shdw_size)
+{
+ int flags = MAP_ANONYMOUS | MAP_PRIVATE;
+ struct mm_struct *mm = current->mm;
+ unsigned long addr, populate, size;
+ *shadow_stack = 0;
+
+ if (!shdw_size)
+ return -EINVAL;
+
+ size = *shdw_size;
+
+ /* If size is 0, then try to calculate yourself */
+ if (size == 0)
+ size = round_up(min_t(unsigned long long, rlimit(RLIMIT_STACK), SZ_4G), PAGE_SIZE);
+ mmap_write_lock(mm);
+ addr = do_mmap(NULL, 0, size, PROT_SHADOWSTACK, flags, 0,
+ &populate, NULL);
+ mmap_write_unlock(mm);
+ if (IS_ERR_VALUE(addr))
+ return PTR_ERR((void *)addr);
+ *shadow_stack_base = addr;
+ *shdw_size = size;
+ return 0;
+}
+
+#if defined(CONFIG_USER_SHADOW_STACK) || defined(CONFIG_USER_INDIRECT_BR_LP)
+/* gets called from load_elf_binary(). This'll setup shadow stack and forward cfi enable */
+int arch_elf_setup_cfi_state(const struct arch_elf_state *state)
+{
+ int ret = 0;
+ unsigned long shadow_stack_base = 0;
+ unsigned long shadow_stk_size = 0;
+ struct thread_info *info = NULL;
+
+ info = current_thread_info();
+ /* setup back cfi state */
+ /* setup cfi state only if implementation supports it */
+ if (arch_supports_shadow_stack() && (state->flags & RISCV_ELF_BCFI)) {
+ info->user_cfi_state.ubcfi_en = 1;
+ ret = allocate_shadow_stack(&shadow_stack_base, &shadow_stk_size);
+ if (ret)
+ return ret;
+
+ info->user_cfi_state.user_shdw_stk = (shadow_stack_base + shadow_stk_size);
+ info->user_cfi_state.shdw_stk_base = shadow_stack_base;
+ }
+ /* setup forward cfi state */
+ if (arch_supports_indirect_br_lp_instr() && (state->flags & RISCV_ELF_FCFI)) {
+ info->user_cfi_state.ufcfi_en = 1;
+ info->user_cfi_state.lp_label = 0;
+ }
+
+ return ret;
+}
+#endif
\ No newline at end of file
--
2.25.1
next prev 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 ` Deepak Gupta [this message]
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 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-9-debug@rivosinc.com \
--to=debug@rivosinc.com \
--cc=aou@eecs.berkeley.edu \
--cc=ebiederm@xmission.com \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.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.