[PATCH v19 00/27] riscv control-flow integrity for usermode

Deepak Gupta posted 27 patches 2 months ago
Documentation/admin-guide/kernel-parameters.txt    |   8 +
Documentation/arch/riscv/index.rst                 |   2 +
Documentation/arch/riscv/zicfilp.rst               | 115 +++++
Documentation/arch/riscv/zicfiss.rst               | 179 +++++++
.../devicetree/bindings/riscv/extensions.yaml      |  14 +
arch/riscv/Kconfig                                 |  21 +
arch/riscv/Makefile                                |   5 +-
arch/riscv/configs/hardening.config                |   4 +
arch/riscv/include/asm/asm-prototypes.h            |   1 +
arch/riscv/include/asm/assembler.h                 |  44 ++
arch/riscv/include/asm/cpufeature.h                |  12 +
arch/riscv/include/asm/csr.h                       |  16 +
arch/riscv/include/asm/entry-common.h              |   2 +
arch/riscv/include/asm/hwcap.h                     |   2 +
arch/riscv/include/asm/mman.h                      |  26 +
arch/riscv/include/asm/mmu_context.h               |   7 +
arch/riscv/include/asm/pgtable.h                   |  30 +-
arch/riscv/include/asm/processor.h                 |   1 +
arch/riscv/include/asm/thread_info.h               |   3 +
arch/riscv/include/asm/usercfi.h                   |  95 ++++
arch/riscv/include/asm/vector.h                    |   3 +
arch/riscv/include/uapi/asm/hwprobe.h              |   2 +
arch/riscv/include/uapi/asm/ptrace.h               |  34 ++
arch/riscv/include/uapi/asm/sigcontext.h           |   1 +
arch/riscv/kernel/Makefile                         |   1 +
arch/riscv/kernel/asm-offsets.c                    |  10 +
arch/riscv/kernel/cpufeature.c                     |  27 +
arch/riscv/kernel/entry.S                          |  38 ++
arch/riscv/kernel/head.S                           |  27 +
arch/riscv/kernel/process.c                        |  27 +-
arch/riscv/kernel/ptrace.c                         |  95 ++++
arch/riscv/kernel/signal.c                         | 148 +++++-
arch/riscv/kernel/sys_hwprobe.c                    |   2 +
arch/riscv/kernel/sys_riscv.c                      |  10 +
arch/riscv/kernel/traps.c                          |  54 ++
arch/riscv/kernel/usercfi.c                        | 545 +++++++++++++++++++++
arch/riscv/kernel/vdso/Makefile                    |  11 +-
arch/riscv/kernel/vdso/flush_icache.S              |   4 +
arch/riscv/kernel/vdso/getcpu.S                    |   4 +
arch/riscv/kernel/vdso/rt_sigreturn.S              |   4 +
arch/riscv/kernel/vdso/sys_hwprobe.S               |   4 +
arch/riscv/kernel/vdso/vgetrandom-chacha.S         |   5 +-
arch/riscv/mm/init.c                               |   2 +-
arch/riscv/mm/pgtable.c                            |  16 +
include/linux/cpu.h                                |   4 +
include/linux/mm.h                                 |   7 +
include/uapi/linux/elf.h                           |   2 +
include/uapi/linux/prctl.h                         |  27 +
kernel/sys.c                                       |  30 ++
tools/testing/selftests/riscv/Makefile             |   2 +-
tools/testing/selftests/riscv/cfi/.gitignore       |   3 +
tools/testing/selftests/riscv/cfi/Makefile         |  16 +
tools/testing/selftests/riscv/cfi/cfi_rv_test.h    |  82 ++++
tools/testing/selftests/riscv/cfi/riscv_cfi_test.c | 173 +++++++
tools/testing/selftests/riscv/cfi/shadowstack.c    | 385 +++++++++++++++
tools/testing/selftests/riscv/cfi/shadowstack.h    |  27 +
56 files changed, 2389 insertions(+), 30 deletions(-)
[PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Deepak Gupta 2 months ago
Basics and overview
===================

Software with larger attack surfaces (e.g. network facing apps like databases,
browsers or apps relying on browser runtimes) suffer from memory corruption
issues which can be utilized by attackers to bend control flow of the program
to eventually gain control (by making their payload executable). Attackers are
able to perform such attacks by leveraging call-sites which rely on indirect
calls or return sites which rely on obtaining return address from stack memory.

To mitigate such attacks, risc-v extension zicfilp enforces that all indirect
calls must land on a landing pad instruction `lpad` else cpu will raise software
check exception (a new cpu exception cause code on riscv).
Similarly for return flow, risc-v extension zicfiss extends architecture with

- `sspush` instruction to push return address on a shadow stack
- `sspopchk` instruction to pop return address from shadow stack
  and compare with input operand (i.e. return address on stack)
- `sspopchk` to raise software check exception if comparision above
  was a mismatch
- Protection mechanism using which shadow stack is not writeable via
  regular store instructions

More information an details can be found at extensions github repo [1].

Equivalent to landing pad (zicfilp) on x86 is `ENDBRANCH` instruction in Intel
CET [3] and branch target identification (BTI) [4] on arm.
Similarly x86's Intel CET has shadow stack [5] and arm64 has guarded control
stack (GCS) [6] which are very similar to risc-v's zicfiss shadow stack.

x86 and arm64 support for user mode shadow stack is already in mainline.

Kernel awareness for user control flow integrity
================================================

This series picks up Samuel Holland's envcfg changes [2] as well. So if those are
being applied independently, they should be removed from this series.

Enabling:

In order to maintain compatibility and not break anything in user mode, kernel
doesn't enable control flow integrity cpu extensions on binary by default.
Instead exposes a prctl interface to enable, disable and lock the shadow stack
or landing pad feature for a task. This allows userspace (loader) to enumerate
if all objects in its address space are compiled with shadow stack and landing
pad support and accordingly enable the feature. Additionally if a subsequent
`dlopen` happens on a library, user mode can take a decision again to disable
the feature (if incoming library is not compiled with support) OR terminate the
task (if user mode policy is strict to have all objects in address space to be
compiled with control flow integirty cpu feature). prctl to enable shadow stack
results in allocating shadow stack from virtual memory and activating for user
address space. x86 and arm64 are also following same direction due to similar
reason(s).

clone/fork:

On clone and fork, cfi state for task is inherited by child. Shadow stack is
part of virtual memory and is a writeable memory from kernel perspective
(writeable via a restricted set of instructions aka shadow stack instructions)
Thus kernel changes ensure that this memory is converted into read-only when
fork/clone happens and COWed when fault is taken due to sspush, sspopchk or
ssamoswap. In case `CLONE_VM` is specified and shadow stack is to be enabled,
kernel will automatically allocate a shadow stack for that clone call.

map_shadow_stack:

x86 introduced `map_shadow_stack` system call to allow user space to explicitly
map shadow stack memory in its address space. It is useful to allocate shadow
for different contexts managed by a single thread (green threads or contexts)
risc-v implements this system call as well.

signal management:

If shadow stack is enabled for a task, kernel performs an asynchronous control
flow diversion to deliver the signal and eventually expects userspace to issue
sigreturn so that original execution can be resumed. Even though resume context
is prepared by kernel, it is in user space memory and is subject to memory
corruption and corruption bugs can be utilized by attacker in this race window
to perform arbitrary sigreturn and eventually bypass cfi mechanism.
Another issue is how to ensure that cfi related state on sigcontext area is not
trampled by legacy apps or apps compiled with old kernel headers.

In order to mitigate control-flow hijacting, kernel prepares a token and place
it on shadow stack before signal delivery and places address of token in
sigcontext structure. During sigreturn, kernel obtains address of token from
sigcontext struture, reads token from shadow stack and validates it and only
then allow sigreturn to succeed. Compatiblity issue is solved by adopting
dynamic sigcontext management introduced for vector extension. This series
re-factor the code little bit to allow future sigcontext management easy (as
proposed by Andy Chiu from SiFive)

config and compilation:

Introduce a new risc-v config option `CONFIG_RISCV_USER_CFI`. Selecting this
config option picks the kernel support for user control flow integrity. This
optin is presented only if toolchain has shadow stack and landing pad support.
And is on purpose guarded by toolchain support. Reason being that eventually
vDSO also needs to be compiled in with shadow stack and landing pad support.
vDSO compile patches are not included as of now because landing pad labeling
scheme is yet to settle for usermode runtime.

To get more information on kernel interactions with respect to
zicfilp and zicfiss, patch series adds documentation for
`zicfilp` and `zicfiss` in following:
Documentation/arch/riscv/zicfiss.rst
Documentation/arch/riscv/zicfilp.rst

How to test this series
=======================

Toolchain
---------
$ git clone git@github.com:sifive/riscv-gnu-toolchain.git -b cfi-dev
$ riscv-gnu-toolchain/configure --prefix=<path-to-where-to-build> --with-arch=rv64gc_zicfilp_zicfiss --enable-linux --disable-gdb  --with-extra-multilib-test="rv64gc_zicfilp_zicfiss-lp64d:-static"
$ make -j$(nproc)

Qemu
----
Get the lastest qemu
$ cd qemu
$ mkdir build
$ cd build
$ ../configure --target-list=riscv64-softmmu
$ make -j$(nproc)

Opensbi
-------
$ git clone git@github.com:deepak0414/opensbi.git -b v6_cfi_spec_split_opensbi
$ make CROSS_COMPILE=<your riscv toolchain> -j$(nproc) PLATFORM=generic

Linux
-----
Running defconfig is fine. CFI is enabled by default if the toolchain
supports it.

$ make ARCH=riscv CROSS_COMPILE=<path-to-cfi-riscv-gnu-toolchain>/build/bin/riscv64-unknown-linux-gnu- -j$(nproc) defconfig
$ make ARCH=riscv CROSS_COMPILE=<path-to-cfi-riscv-gnu-toolchain>/build/bin/riscv64-unknown-linux-gnu- -j$(nproc)

In case you're building your own rootfs using toolchain, please make sure you
pick following patch to ensure that vDSO compiled with lpad and shadow stack.

"arch/riscv: compile vdso with landing pad"

Branch where above patch can be picked
https://github.com/deepak0414/linux-riscv-cfi/tree/vdso_user_cfi_v6.12-rc1

Running
-------

Modify your qemu command to have:
-bios <path-to-cfi-opensbi>/build/platform/generic/firmware/fw_dynamic.bin
-cpu rv64,zicfilp=true,zicfiss=true,zimop=true,zcmop=true

vDSO related Opens (in the flux)
=================================

I am listing these opens for laying out plan and what to expect in future
patch sets. And of course for the sake of discussion.

Shadow stack and landing pad enabling in vDSO
----------------------------------------------
vDSO must have shadow stack and landing pad support compiled in for task
to have shadow stack and landing pad support. This patch series doesn't
enable that (yet). Enabling shadow stack support in vDSO should be
straight forward (intend to do that in next versions of patch set). Enabling
landing pad support in vDSO requires some collaboration with toolchain folks
to follow a single label scheme for all object binaries. This is necessary to
ensure that all indirect call-sites are setting correct label and target landing
pads are decorated with same label scheme.

How many vDSOs
---------------
Shadow stack instructions are carved out of zimop (may be operations) and if CPU
doesn't implement zimop, they're illegal instructions. Kernel could be running on
a CPU which may or may not implement zimop. And thus kernel will have to carry 2
different vDSOs and expose the appropriate one depending on whether CPU implements
zimop or not.

References
==========
[1] - https://github.com/riscv/riscv-cfi
[2] - https://lore.kernel.org/all/20240814081126.956287-1-samuel.holland@sifive.com/
[3] - https://lwn.net/Articles/889475/
[4] - https://developer.arm.com/documentation/109576/0100/Branch-Target-Identification
[5] - https://www.intel.com/content/dam/develop/external/us/en/documents/catc17-introduction-intel-cet-844137.pdf
[6] - https://lwn.net/Articles/940403/

To: Thomas Gleixner <tglx@linutronix.de>
To: Ingo Molnar <mingo@redhat.com>
To: Borislav Petkov <bp@alien8.de>
To: Dave Hansen <dave.hansen@linux.intel.com>
To: x86@kernel.org
To: H. Peter Anvin <hpa@zytor.com>
To: Andrew Morton <akpm@linux-foundation.org>
To: Liam R. Howlett <Liam.Howlett@oracle.com>
To: Vlastimil Babka <vbabka@suse.cz>
To: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
To: Paul Walmsley <paul.walmsley@sifive.com>
To: Palmer Dabbelt <palmer@dabbelt.com>
To: Albert Ou <aou@eecs.berkeley.edu>
To: Conor Dooley <conor@kernel.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Arnd Bergmann <arnd@arndb.de>
To: Christian Brauner <brauner@kernel.org>
To: Peter Zijlstra <peterz@infradead.org>
To: Oleg Nesterov <oleg@redhat.com>
To: Eric Biederman <ebiederm@xmission.com>
To: Kees Cook <kees@kernel.org>
To: Jonathan Corbet <corbet@lwn.net>
To: Shuah Khan <shuah@kernel.org>
To: Jann Horn <jannh@google.com>
To: Conor Dooley <conor+dt@kernel.org>
To: Miguel Ojeda <ojeda@kernel.org>
To: Alex Gaynor <alex.gaynor@gmail.com>
To: Boqun Feng <boqun.feng@gmail.com>
To: Gary Guo <gary@garyguo.net>
To: Björn Roy Baron <bjorn3_gh@protonmail.com>
To: Benno Lossin <benno.lossin@proton.me>
To: Andreas Hindborg <a.hindborg@kernel.org>
To: Alice Ryhl <aliceryhl@google.com>
To: Trevor Gross <tmgross@umich.edu>
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-riscv@lists.infradead.org
Cc: devicetree@vger.kernel.org
Cc: linux-arch@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Cc: alistair.francis@wdc.com
Cc: richard.henderson@linaro.org
Cc: jim.shu@sifive.com
Cc: andybnac@gmail.com
Cc: kito.cheng@sifive.com
Cc: charlie@rivosinc.com
Cc: atishp@rivosinc.com
Cc: evan@rivosinc.com
Cc: cleger@rivosinc.com
Cc: alexghiti@rivosinc.com
Cc: samitolvanen@google.com
Cc: broonie@kernel.org
Cc: rick.p.edgecombe@intel.com
Cc: rust-for-linux@vger.kernel.org

changelog
---------
v19:
- riscv_nousercfi was `int`. changed it to unsigned long.
  Thanks to Alex Ghiti for reporting it. It was a bug.
- ELP is cleared on trap entry only when CONFIG_64BIT.
- restore ssp back on return to usermode was being done
  before `riscv_v_context_nesting_end` on trap exit path.
  If kernel shadow stack were enabled this would result in
  kernel operating on user shadow stack and panic (as I found
  in my testing of kcfi patch series). So fixed that.

v18:
- rebased on 6.16-rc1
- uprobe handling clears ELP in sstatus image in pt_regs
- vdso was missing shadow stack elf note for object files.
  added that. Additional asm file for vdso needed the elf marker
  flag. toolchain should complain if `-fcf-protection=full` and
  marker is missing for object generated from asm file. Asked
  toolchain folks to fix this. Although no reason to gate the merge
  on that.
- Split up compile options for march and fcf-protection in vdso
  Makefile
- CONFIG_RISCV_USER_CFI option is moved under "Kernel features" menu
  Added `arch/riscv/configs/hardening.config` fragment which selects
  CONFIG_RISCV_USER_CFI

v17:
- fixed warnings due to empty macros in usercfi.h (reported by alexg)
- fixed prefixes in commit titles reported by alexg
- took below uprobe with fcfi v2 patch from Zong Li and squashed it with
  "riscv/traps: Introduce software check exception and uprobe handling"
  https://lore.kernel.org/all/20250604093403.10916-1-zong.li@sifive.com/

v16:
- If FWFT is not implemented or returns error for shadow stack activation, then
  no_usercfi is set to disable shadow stack. Although this should be picked up
  by extension validation and activation. Fixed this bug for zicfilp and zicfiss
  both. Thanks to Charlie Jenkins for reporting this.
- If toolchain doesn't support cfi, cfi kselftest shouldn't build. Suggested by
  Charlie Jenkins.
- Default for CONFIG_RISCV_USER_CFI is set to no. Charlie/Atish suggested to
  keep it off till we have more hardware availibility with RVA23 profile and
  zimop/zcmop implemented. Else this will start breaking people's workflow
- Includes the fix if "!RV64 and !SBI" then definitions for FWFT in
  asm-offsets.c error.

v15:
- Toolchain has been updated to include `-fcf-protection` flag. This
  exists for x86 as well. Updated kernel patches to compile vDSO and
  selftest to compile with `fcf-protection=full` flag.
- selecting CONFIG_RISCV_USERCFI selects CONFIG_RISCV_SBI.
- Patch to enable shadow stack for kernel wasn't hidden behind
  CONFIG_RISCV_USERCFI and CONFIG_RISCV_SBI. fixed that.

v14:
- rebased on top of palmer/sbi-v3. Thus dropped clement's FWFT patches
  Updated RISCV_ISA_EXT_XXXX in hwcap and hwprobe constants.
- Took Radim's suggestions on bitfields.
- Placed cfi_state at the end of thread_info block so that current situation
  is not disturbed with respect to member fields of thread_info in single
  cacheline.

v13:
- cpu_supports_shadow_stack/cpu_supports_indirect_br_lp_instr uses
  riscv_has_extension_unlikely()
- uses nops(count) to create nop slide
- RISCV_ACQUIRE_BARRIER is not needed in `amo_user_shstk`. Removed it
- changed ternaries to simply use implicit casting to convert to bool.
- kernel command line allows to disable zicfilp and zicfiss independently.
  updated kernel-parameters.txt.
- ptrace user abi for cfi uses bitmasks instead of bitfields. Added ptrace
  kselftest.
- cosmetic and grammatical changes to documentation.

v12:
- It seems like I had accidently squashed arch agnostic indirect branch
  tracking prctl and riscv implementation of those prctls. Split them again.
- set_shstk_status/set_indir_lp_status perform CSR writes only when CPU
  support is available. As suggested by Zong Li.
- Some minor clean up in kselftests as suggested by Zong Li.

v11:
- patch "arch/riscv: compile vdso with landing pad" was unconditionally
  selecting `_zicfilp` for vDSO compile. fixed that. Changed `lpad 1` to
  to `lpad 0`. 
v10:
- dropped "mm: helper `is_shadow_stack_vma` to check shadow stack vma". This patch
  is not that interesting to this patch series for risc-v. There are instances in
  arch directories where VM_SHADOW_STACK flag is anyways used. Dropping this patch
  to expedite merging in riscv tree.
- Took suggestions from `Clement` on "riscv: zicfiss / zicfilp enumeration" to
  validate presence of cfi based on config.
- Added a patch for vDSO to have `lpad 0`. I had omitted this earlier to make sure
  we add single vdso object with cfi enabled. But a vdso object with scheme of 
  zero labeled landing pad is least common denominator and should work with all
  objects of zero labeled as well as function-signature labeled objects.

v9:
- rebased on master (39a803b754d5 fix braino in "9p: fix ->rename_sem exclusion")
- dropped "mm: Introduce ARCH_HAS_USER_SHADOW_STACK" (master has it from arm64/gcs)
- dropped "prctl: arch-agnostic prctl for shadow stack" (master has it from arm64/gcs)

v8:
- rebased on palmer/for-next
- dropped samuel holland's `envcfg` context switch patches.
  they are in parlmer/for-next
  
v7:
- Removed "riscv/Kconfig: enable HAVE_EXIT_THREAD for riscv"
  Instead using `deactivate_mm` flow to clean up.
  see here for more context
  https://lore.kernel.org/all/20230908203655.543765-1-rick.p.edgecombe@intel.com/#t
- Changed the header include in `kselftest`. Hopefully this fixes compile
  issue faced by Zong Li at SiFive.
- Cleaned up an orphaned change to `mm/mmap.c` in below patch
  "riscv/mm : ensure PROT_WRITE leads to VM_READ | VM_WRITE"
- Lock interfaces for shadow stack and indirect branch tracking expect arg == 0
  Any future evolution of this interface should accordingly define how arg should
  be setup.
- `mm/map.c` has an instance of using `VM_SHADOW_STACK`. Fixed it to use helper
  `is_shadow_stack_vma`.
- Link to v6: https://lore.kernel.org/r/20241008-v5_user_cfi_series-v6-0-60d9fe073f37@rivosinc.com

v6:
- Picked up Samuel Holland's changes as is with `envcfg` placed in
  `thread` instead of `thread_info`
- fixed unaligned newline escapes in kselftest
- cleaned up messages in kselftest and included test output in commit message
- fixed a bug in clone path reported by Zong Li
- fixed a build issue if CONFIG_RISCV_ISA_V is not selected
  (this was introduced due to re-factoring signal context
  management code)

v5:
- rebased on v6.12-rc1
- Fixed schema related issues in device tree file
- Fixed some of the documentation related issues in zicfilp/ss.rst
  (style issues and added index)
- added `SHADOW_STACK_SET_MARKER` so that implementation can define base
  of shadow stack.
- Fixed warnings on definitions added in usercfi.h when
  CONFIG_RISCV_USER_CFI is not selected.
- Adopted context header based signal handling as proposed by Andy Chiu
- Added support for enabling kernel mode access to shadow stack using
  FWFT
  (https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-firmware-features.adoc)
- Link to v5: https://lore.kernel.org/r/20241001-v5_user_cfi_series-v1-0-3ba65b6e550f@rivosinc.com
  (Note: I had an issue in my workflow due to which version number wasn't
  picked up correctly while sending out patches)

v4:
- rebased on 6.11-rc6
- envcfg: Converged with Samuel Holland's patches for envcfg management on per-
thread basis.
- vma_is_shadow_stack is renamed to is_vma_shadow_stack
- picked up Mark Brown's `ARCH_HAS_USER_SHADOW_STACK` patch
- signal context: using extended context management to maintain compatibility.
- fixed `-Wmissing-prototypes` compiler warnings for prctl functions
- Documentation fixes and amending typos.
- Link to v4: https://lore.kernel.org/all/20240912231650.3740732-1-debug@rivosinc.com/

v3:
- envcfg
  logic to pick up base envcfg had a bug where `ENVCFG_CBZE` could have been
  picked on per task basis, even though CPU didn't implement it. Fixed in
   this series.

- dt-bindings
  As suggested, split into separate commit. fixed the messaging that spec is
  in public review

- arch_is_shadow_stack change
  arch_is_shadow_stack changed to vma_is_shadow_stack

- hwprobe
  zicfiss / zicfilp if present will get enumerated in hwprobe

- selftests
  As suggested, added object and binary filenames to .gitignore
  Selftest binary anyways need to be compiled with cfi enabled compiler which
  will make sure that landing pad and shadow stack are enabled. Thus removed
  separate enable/disable tests. Cleaned up tests a bit.

- Link to v3: https://lore.kernel.org/lkml/20240403234054.2020347-1-debug@rivosinc.com/

v2:
- Using config `CONFIG_RISCV_USER_CFI`, kernel support for riscv control flow
  integrity for user mode programs can be compiled in the kernel.

- Enabling of control flow integrity for user programs is left to user runtime

- This patch series introduces arch agnostic `prctls` to enable shadow stack
  and indirect branch tracking. And implements them on riscv.

---
Changes in v19:
- Link to v18: https://lore.kernel.org/r/20250711-v5_user_cfi_series-v18-0-a8ee62f9f38e@rivosinc.com

Changes in v18:
- Link to v17: https://lore.kernel.org/r/20250604-v5_user_cfi_series-v17-0-4565c2cf869f@rivosinc.com

Changes in v17:
- Link to v16: https://lore.kernel.org/r/20250522-v5_user_cfi_series-v16-0-64f61a35eee7@rivosinc.com

Changes in v16:
- Link to v15: https://lore.kernel.org/r/20250502-v5_user_cfi_series-v15-0-914966471885@rivosinc.com

Changes in v15:
- changelog posted just below cover letter
- Link to v14: https://lore.kernel.org/r/20250429-v5_user_cfi_series-v14-0-5239410d012a@rivosinc.com

Changes in v14:

- changelog posted just below cover letter
- Link to v13: https://lore.kernel.org/r/20250424-v5_user_cfi_series-v13-0-971437de586a@rivosinc.com

Changes in v13:
- changelog posted just below cover letter
- Link to v12: https://lore.kernel.org/r/20250314-v5_user_cfi_series-v12-0-e51202b53138@rivosinc.com

Changes in v12:
- changelog posted just below cover letter
- Link to v11: https://lore.kernel.org/r/20250310-v5_user_cfi_series-v11-0-86b36cbfb910@rivosinc.com

Changes in v11:
- changelog posted just below cover letter
- Link to v10: https://lore.kernel.org/r/20250210-v5_user_cfi_series-v10-0-163dcfa31c60@rivosinc.com

---
Andy Chiu (1):
      riscv: signal: abstract header saving for setup_sigcontext

Deepak Gupta (25):
      mm: VM_SHADOW_STACK definition for riscv
      dt-bindings: riscv: zicfilp and zicfiss in dt-bindings (extensions.yaml)
      riscv: zicfiss / zicfilp enumeration
      riscv: zicfiss / zicfilp extension csr and bit definitions
      riscv: usercfi state for task and save/restore of CSR_SSP on trap entry/exit
      riscv/mm : ensure PROT_WRITE leads to VM_READ | VM_WRITE
      riscv/mm: manufacture shadow stack pte
      riscv/mm: teach pte_mkwrite to manufacture shadow stack PTEs
      riscv/mm: write protect and shadow stack
      riscv/mm: Implement map_shadow_stack() syscall
      riscv/shstk: If needed allocate a new shadow stack on clone
      riscv: Implements arch agnostic shadow stack prctls
      prctl: arch-agnostic prctl for indirect branch tracking
      riscv: Implements arch agnostic indirect branch tracking prctls
      riscv/traps: Introduce software check exception and uprobe handling
      riscv/signal: save and restore of shadow stack for signal
      riscv/kernel: update __show_regs to print shadow stack register
      riscv/ptrace: riscv cfi status and state via ptrace and in core files
      riscv/hwprobe: zicfilp / zicfiss enumeration in hwprobe
      riscv: kernel command line option to opt out of user cfi
      riscv: enable kernel access to shadow stack memory via FWFT sbi call
      riscv: create a config for shadow stack and landing pad instr support
      riscv: Documentation for landing pad / indirect branch tracking
      riscv: Documentation for shadow stack on riscv
      kselftest/riscv: kselftest for user mode cfi

Jim Shu (1):
      arch/riscv: compile vdso with landing pad and shadow stack note

 Documentation/admin-guide/kernel-parameters.txt    |   8 +
 Documentation/arch/riscv/index.rst                 |   2 +
 Documentation/arch/riscv/zicfilp.rst               | 115 +++++
 Documentation/arch/riscv/zicfiss.rst               | 179 +++++++
 .../devicetree/bindings/riscv/extensions.yaml      |  14 +
 arch/riscv/Kconfig                                 |  21 +
 arch/riscv/Makefile                                |   5 +-
 arch/riscv/configs/hardening.config                |   4 +
 arch/riscv/include/asm/asm-prototypes.h            |   1 +
 arch/riscv/include/asm/assembler.h                 |  44 ++
 arch/riscv/include/asm/cpufeature.h                |  12 +
 arch/riscv/include/asm/csr.h                       |  16 +
 arch/riscv/include/asm/entry-common.h              |   2 +
 arch/riscv/include/asm/hwcap.h                     |   2 +
 arch/riscv/include/asm/mman.h                      |  26 +
 arch/riscv/include/asm/mmu_context.h               |   7 +
 arch/riscv/include/asm/pgtable.h                   |  30 +-
 arch/riscv/include/asm/processor.h                 |   1 +
 arch/riscv/include/asm/thread_info.h               |   3 +
 arch/riscv/include/asm/usercfi.h                   |  95 ++++
 arch/riscv/include/asm/vector.h                    |   3 +
 arch/riscv/include/uapi/asm/hwprobe.h              |   2 +
 arch/riscv/include/uapi/asm/ptrace.h               |  34 ++
 arch/riscv/include/uapi/asm/sigcontext.h           |   1 +
 arch/riscv/kernel/Makefile                         |   1 +
 arch/riscv/kernel/asm-offsets.c                    |  10 +
 arch/riscv/kernel/cpufeature.c                     |  27 +
 arch/riscv/kernel/entry.S                          |  38 ++
 arch/riscv/kernel/head.S                           |  27 +
 arch/riscv/kernel/process.c                        |  27 +-
 arch/riscv/kernel/ptrace.c                         |  95 ++++
 arch/riscv/kernel/signal.c                         | 148 +++++-
 arch/riscv/kernel/sys_hwprobe.c                    |   2 +
 arch/riscv/kernel/sys_riscv.c                      |  10 +
 arch/riscv/kernel/traps.c                          |  54 ++
 arch/riscv/kernel/usercfi.c                        | 545 +++++++++++++++++++++
 arch/riscv/kernel/vdso/Makefile                    |  11 +-
 arch/riscv/kernel/vdso/flush_icache.S              |   4 +
 arch/riscv/kernel/vdso/getcpu.S                    |   4 +
 arch/riscv/kernel/vdso/rt_sigreturn.S              |   4 +
 arch/riscv/kernel/vdso/sys_hwprobe.S               |   4 +
 arch/riscv/kernel/vdso/vgetrandom-chacha.S         |   5 +-
 arch/riscv/mm/init.c                               |   2 +-
 arch/riscv/mm/pgtable.c                            |  16 +
 include/linux/cpu.h                                |   4 +
 include/linux/mm.h                                 |   7 +
 include/uapi/linux/elf.h                           |   2 +
 include/uapi/linux/prctl.h                         |  27 +
 kernel/sys.c                                       |  30 ++
 tools/testing/selftests/riscv/Makefile             |   2 +-
 tools/testing/selftests/riscv/cfi/.gitignore       |   3 +
 tools/testing/selftests/riscv/cfi/Makefile         |  16 +
 tools/testing/selftests/riscv/cfi/cfi_rv_test.h    |  82 ++++
 tools/testing/selftests/riscv/cfi/riscv_cfi_test.c | 173 +++++++
 tools/testing/selftests/riscv/cfi/shadowstack.c    | 385 +++++++++++++++
 tools/testing/selftests/riscv/cfi/shadowstack.h    |  27 +
 56 files changed, 2389 insertions(+), 30 deletions(-)
---
base-commit: a2a05801de77ca5122fc34e3eb84d6359ef70389
change-id: 20240930-v5_user_cfi_series-3dc332f8f5b2
--
- debug

Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Paul Walmsley 1 week, 3 days ago
Hi,

On Thu, 31 Jul 2025, Deepak Gupta wrote:

[ ... ]

> vDSO related Opens (in the flux)
> =================================
> 
> I am listing these opens for laying out plan and what to expect in future
> patch sets. And of course for the sake of discussion.
> 

[ ... ]

> How many vDSOs
> ---------------
> Shadow stack instructions are carved out of zimop (may be operations) and if CPU
> doesn't implement zimop, they're illegal instructions. Kernel could be running on
> a CPU which may or may not implement zimop. And thus kernel will have to carry 2
> different vDSOs and expose the appropriate one depending on whether CPU implements
> zimop or not.

If we merge this series without this, then when CFI is enabled in the 
Kconfig, we'll wind up with a non-portable kernel that won't run on older 
hardware.  We go to great lengths to enable kernel binary portability 
across the presence or absence of other RISC-V extensions, and I think 
these CFI extensions should be no different.

So before considering this for merging, I'd like to see at least an 
attempt to implement the dual-vDSO approach (or something equivalent) 
where the same kernel binary with CFI enabled can run on both pre-Zimop 
and post-Zimop hardware, with the existing userspaces that are common 
today.

thanks Deepak,

- Paul
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Charles Mirabile 1 week, 1 day ago
Hi - 

Hoping that I got everything right with git-send-email so that this is
delivered alright...

Wanted to jump in to head off a potential talking past one another / 
miscommunication situation I see here.

On Wed, Sep 24, 2025 at 08:36:11AM -0600, Paul Walmsley wrote:
> Hi,
> 
> On Thu, 31 Jul 2025, Deepak Gupta wrote:
> 
> [ ... ]
> 
> > vDSO related Opens (in the flux)
> > =================================
> > 
> > I am listing these opens for laying out plan and what to expect in future
> > patch sets. And of course for the sake of discussion.
> > 
> 
> [ ... ]
> 
> > How many vDSOs
> > ---------------
> > Shadow stack instructions are carved out of zimop (may be operations) and if CPU
> > doesn't implement zimop, they're illegal instructions. Kernel could be running on
> > a CPU which may or may not implement zimop. And thus kernel will have to carry 2
> > different vDSOs and expose the appropriate one depending on whether CPU implements
> > zimop or not.
> 
> If we merge this series without this, then when CFI is enabled in the 
> Kconfig, we'll wind up with a non-portable kernel that won't run on older 
> hardware.  We go to great lengths to enable kernel binary portability 
> across the presence or absence of other RISC-V extensions, and I think 
> these CFI extensions should be no different.

That is not true, this series does not contain the VDSO changes so it can
be merged as is.

> 
> So before considering this for merging, I'd like to see at least an 
> attempt to implement the dual-vDSO approach (or something equivalent) 
> where the same kernel binary with CFI enabled can run on both pre-Zimop 
> and post-Zimop hardware, with the existing userspaces that are common 
> today.

I agree that when the VDSO patches are submitted for inclusion they should
be written in a way that avoids limiting the entire kernel to either
pre-Zimop or post-Zimop hardware based on the config, but I think it
should be quite possible to perform e.g. runtime patching of the VDSO
to replace the Zimop instructions with nops if the config is enabled but
the hardware does not support Zimop.

However, that concern should not hold up this patch series. Raise it again
when the VDSO patches are posted.

> 
> thanks Deepak,
> 
> - Paul

Best - Charlie
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Deepak Gupta 1 week, 1 day ago
Hi Charles,

Thanks for response. Rest inline

On Fri, Sep 26, 2025 at 03:29:19PM -0400, Charles Mirabile wrote:
>Hi -
>
>Hoping that I got everything right with git-send-email so that this is
>delivered alright...
>
>Wanted to jump in to head off a potential talking past one another /
>miscommunication situation I see here.
>
>On Wed, Sep 24, 2025 at 08:36:11AM -0600, Paul Walmsley wrote:
>> Hi,
>>
>> On Thu, 31 Jul 2025, Deepak Gupta wrote:
>>
>> [ ... ]
>>
>> > vDSO related Opens (in the flux)
>> > =================================
>> >
>> > I am listing these opens for laying out plan and what to expect in future
>> > patch sets. And of course for the sake of discussion.
>> >
>>
>> [ ... ]
>>
>> > How many vDSOs
>> > ---------------
>> > Shadow stack instructions are carved out of zimop (may be operations) and if CPU
>> > doesn't implement zimop, they're illegal instructions. Kernel could be running on
>> > a CPU which may or may not implement zimop. And thus kernel will have to carry 2
>> > different vDSOs and expose the appropriate one depending on whether CPU implements
>> > zimop or not.
>>
>> If we merge this series without this, then when CFI is enabled in the
>> Kconfig, we'll wind up with a non-portable kernel that won't run on older
>> hardware.  We go to great lengths to enable kernel binary portability
>> across the presence or absence of other RISC-V extensions, and I think
>> these CFI extensions should be no different.
>
>That is not true, this series does not contain the VDSO changes so it can
>be merged as is.

Look at patch 23/27. It does have vDSO change. Although shadow stack
instruction are inserted as compiled flag for vDSO only when cfi config is
selected by user. Right now default is "No". So it won't impact anyone unles
user explicitly says "Yes".

>
>>
>> So before considering this for merging, I'd like to see at least an
>> attempt to implement the dual-vDSO approach (or something equivalent)
>> where the same kernel binary with CFI enabled can run on both pre-Zimop
>> and post-Zimop hardware, with the existing userspaces that are common
>> today.
>
>I agree that when the VDSO patches are submitted for inclusion they should
>be written in a way that avoids limiting the entire kernel to either
>pre-Zimop or post-Zimop hardware based on the config, but I think it
>should be quite possible to perform e.g. runtime patching of the VDSO
>to replace the Zimop instructions with nops if the config is enabled but
>the hardware does not support Zimop.

Why kernel need to do this extra work of carry two binaries and patching it
runtime?

If for instance we do this, and then this allow this kernel to be taken to
pre-Zimop hardware, it is assumed that entire userspace for such hardware
was compiled without shadow stack (thus no zimop). In that case, kernel
should have been compiled without CFI option.

Just for sake of thought exercise, let's say Fedora 43 is first release with
RVA23 compatiblity (zimop and shadow stack), there is no way this and future
release will be able to run on pre-zimop hardware. Unless redhat is going to
start two different binary distribution. One for pre-zimop and one for
post-zimop. If that would be the case, then compiling two different kernel for
such two different hardware would be least of the worry.

Only other usecase is of a seasoned kernel developer or build your own stuff
in embedded environment, those users can anyways are advanced users. But it
forces complexity on rest of kernel. There will be more extensions taking zimop
encodings in future, we will end up patching vDSO and keep this complexity
while rest of the userspace will not be patched and will be separate binary
distribution (if OS distros endup distributing multiple binaries per release)

>
>However, that concern should not hold up this patch series. Raise it again
>when the VDSO patches are posted.

As I said earlier, these changes default cfi config to No. So whenever this
is selected "Yes" by a distro, they can drive such patches (if there is a real
need)

>
>>
>> thanks Deepak,
>>
>> - Paul
>
>Best - Charlie
>
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Charles Mirabile 1 week, 1 day ago
Hi Deepak -

On Fri, Sep 26, 2025 at 3:57 PM Deepak Gupta <debug@rivosinc.com> wrote:
>
> Hi Charles,
>
> Thanks for response. Rest inline
>
> On Fri, Sep 26, 2025 at 03:29:19PM -0400, Charles Mirabile wrote:
> >Hi -
> >
> >Hoping that I got everything right with git-send-email so that this is
> >delivered alright...
> >
> >Wanted to jump in to head off a potential talking past one another /
> >miscommunication situation I see here.
> >
> >On Wed, Sep 24, 2025 at 08:36:11AM -0600, Paul Walmsley wrote:
> >> Hi,
> >>
> >> On Thu, 31 Jul 2025, Deepak Gupta wrote:
> >>
> >> [ ... ]
> >>
> >> > vDSO related Opens (in the flux)
> >> > =================================
> >> >
> >> > I am listing these opens for laying out plan and what to expect in future
> >> > patch sets. And of course for the sake of discussion.
> >> >
> >>
> >> [ ... ]
> >>
> >> > How many vDSOs
> >> > ---------------
> >> > Shadow stack instructions are carved out of zimop (may be operations) and if CPU
> >> > doesn't implement zimop, they're illegal instructions. Kernel could be running on
> >> > a CPU which may or may not implement zimop. And thus kernel will have to carry 2
> >> > different vDSOs and expose the appropriate one depending on whether CPU implements
> >> > zimop or not.
> >>
> >> If we merge this series without this, then when CFI is enabled in the
> >> Kconfig, we'll wind up with a non-portable kernel that won't run on older
> >> hardware.  We go to great lengths to enable kernel binary portability
> >> across the presence or absence of other RISC-V extensions, and I think
> >> these CFI extensions should be no different.
> >
> >That is not true, this series does not contain the VDSO changes so it can
> >be merged as is.
>
> Look at patch 23/27. It does have vDSO change. Although shadow stack
> instruction are inserted as compiled flag for vDSO only when cfi config is
> selected by user. Right now default is "No". So it won't impact anyone unles
> user explicitly says "Yes".

Yes sorry I caught that after hitting send and replied to my own email
(but then I said 19/27 instead of 23/27 *facepalm*)

>
> >
> >>
> >> So before considering this for merging, I'd like to see at least an
> >> attempt to implement the dual-vDSO approach (or something equivalent)
> >> where the same kernel binary with CFI enabled can run on both pre-Zimop
> >> and post-Zimop hardware, with the existing userspaces that are common
> >> today.
> >
> >I agree that when the VDSO patches are submitted for inclusion they should
> >be written in a way that avoids limiting the entire kernel to either
> >pre-Zimop or post-Zimop hardware based on the config, but I think it
> >should be quite possible to perform e.g. runtime patching of the VDSO
> >to replace the Zimop instructions with nops if the config is enabled but
> >the hardware does not support Zimop.
>
> Why kernel need to do this extra work of carry two binaries and patching it
> runtime?
>
> If for instance we do this, and then this allow this kernel to be taken to
> pre-Zimop hardware, it is assumed that entire userspace for such hardware
> was compiled without shadow stack (thus no zimop). In that case, kernel
> should have been compiled without CFI option.

You raise a good point, it just breaks the tradition of runtime
detection and backwards compat that has been the standard for riscv
extensions in the kernel so far.

It would be nice if a kernel could be built that would run on both
pre-Zimop and post-Zimop hardware and be able to offer CFI to
userspace when running on hardware with Zimop (and Zicfiss / Zicfilp)
but agree that it is a burden.

>
> Just for sake of thought exercise, let's say Fedora 43 is first release with
> RVA23 compatiblity (zimop and shadow stack), there is no way this and future
> release will be able to run on pre-zimop hardware. Unless redhat is going to
> start two different binary distribution. One for pre-zimop and one for
> post-zimop. If that would be the case, then compiling two different kernel for
> such two different hardware would be least of the worry.

It would be one thing if there were hardware supporting
Zimop/Zicfiss/Zicfilp readily available, but I am not aware of any
platform other than qemu to test this code. Since it breaks
compatibility with hardware I am not sure anyone will be able to do
anything with this config option and it moves the burden on to each
distro to go in and specifically enabling it vs just making things
work to get important security improvements if the hardware has
support and not if it doesn't in a backwards compatible way.

>
> Only other usecase is of a seasoned kernel developer or build your own stuff
> in embedded environment, those users can anyways are advanced users. But it
> forces complexity on rest of kernel. There will be more extensions taking zimop
> encodings in future, we will end up patching vDSO and keep this complexity
> while rest of the userspace will not be patched and will be separate binary
> distribution (if OS distros endup distributing multiple binaries per release)
>
> >
> >However, that concern should not hold up this patch series. Raise it again
> >when the VDSO patches are posted.
>
> As I said earlier, these changes default cfi config to No. So whenever this
> is selected "Yes" by a distro, they can drive such patches (if there is a real
> need)

If we did the patching we could make this config default to yes to
that you are building a kernel that is set up to be able to offer CFI
when running on hardware which supports it as long as you have a
toolchain that recognizes the extensions which I think would be good
for moving this important security feature forward.

>
> >
> >>
> >> thanks Deepak,
> >>
> >> - Paul
> >
> >Best - Charlie
> >
>

Sorry for stirring the pot on this. I really appreciate your work on
this patch series.

I agree that this is a difficult call, and I could see it going either
way but I lean towards trying to maintain the backwards compatibility
because the hardware doesn't exist yet.

Best - Charlie
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Deepak Gupta 1 week, 1 day ago
On Fri, Sep 26, 2025 at 04:28:58PM -0400, Charles Mirabile wrote:
>Hi Deepak -
>
>On Fri, Sep 26, 2025 at 3:57 PM Deepak Gupta <debug@rivosinc.com> wrote:
>>
>> Hi Charles,
>>
>> Thanks for response. Rest inline
>>
>> On Fri, Sep 26, 2025 at 03:29:19PM -0400, Charles Mirabile wrote:
>> >Hi -
>> >
>> >Hoping that I got everything right with git-send-email so that this is
>> >delivered alright...
>> >
>> >Wanted to jump in to head off a potential talking past one another /
>> >miscommunication situation I see here.
>> >
>> >On Wed, Sep 24, 2025 at 08:36:11AM -0600, Paul Walmsley wrote:
>> >> Hi,
>> >>
>> >> On Thu, 31 Jul 2025, Deepak Gupta wrote:
>> >>
>> >> [ ... ]
>> >>
>> >> > vDSO related Opens (in the flux)
>> >> > =================================
>> >> >
>> >> > I am listing these opens for laying out plan and what to expect in future
>> >> > patch sets. And of course for the sake of discussion.
>> >> >
>> >>
>> >> [ ... ]
>> >>
>> >> > How many vDSOs
>> >> > ---------------
>> >> > Shadow stack instructions are carved out of zimop (may be operations) and if CPU
>> >> > doesn't implement zimop, they're illegal instructions. Kernel could be running on
>> >> > a CPU which may or may not implement zimop. And thus kernel will have to carry 2
>> >> > different vDSOs and expose the appropriate one depending on whether CPU implements
>> >> > zimop or not.
>> >>
>> >> If we merge this series without this, then when CFI is enabled in the
>> >> Kconfig, we'll wind up with a non-portable kernel that won't run on older
>> >> hardware.  We go to great lengths to enable kernel binary portability
>> >> across the presence or absence of other RISC-V extensions, and I think
>> >> these CFI extensions should be no different.
>> >
>> >That is not true, this series does not contain the VDSO changes so it can
>> >be merged as is.
>>
>> Look at patch 23/27. It does have vDSO change. Although shadow stack
>> instruction are inserted as compiled flag for vDSO only when cfi config is
>> selected by user. Right now default is "No". So it won't impact anyone unles
>> user explicitly says "Yes".
>
>Yes sorry I caught that after hitting send and replied to my own email
>(but then I said 19/27 instead of 23/27 *facepalm*)
>
>>
>> >
>> >>
>> >> So before considering this for merging, I'd like to see at least an
>> >> attempt to implement the dual-vDSO approach (or something equivalent)
>> >> where the same kernel binary with CFI enabled can run on both pre-Zimop
>> >> and post-Zimop hardware, with the existing userspaces that are common
>> >> today.
>> >
>> >I agree that when the VDSO patches are submitted for inclusion they should
>> >be written in a way that avoids limiting the entire kernel to either
>> >pre-Zimop or post-Zimop hardware based on the config, but I think it
>> >should be quite possible to perform e.g. runtime patching of the VDSO
>> >to replace the Zimop instructions with nops if the config is enabled but
>> >the hardware does not support Zimop.
>>
>> Why kernel need to do this extra work of carry two binaries and patching it
>> runtime?
>>
>> If for instance we do this, and then this allow this kernel to be taken to
>> pre-Zimop hardware, it is assumed that entire userspace for such hardware
>> was compiled without shadow stack (thus no zimop). In that case, kernel
>> should have been compiled without CFI option.
>
>You raise a good point, it just breaks the tradition of runtime
>detection and backwards compat that has been the standard for riscv
>extensions in the kernel so far.

riscv (and others arches) have been able to do that because of "alternatives".
It's just that due to composable nature of riscv, alternatives are just spread
everywhere in the code and feels like riscv is doing something unique here.
Whenever there is a surgical placement of certain instructions in kernel, it
could be hidden behind alternatives and be patched in runtime.

However situations where instructions are emitted as part of codegen, there is
no hiding. Either it works or it doesn't. If we have auto vectorization enabled
in usermode, such a binary won't run on hardware which doesn't implement vector.

In case of shadow stack, it similar situation. If enabled compiler decides to
insert sspush and sspopchk. They necessarily won't be prologue or epilogue but
somewhere in function body as deemed fit by compiler, thus increasing the
complexity of runtime patching.

More so, here are wishing for kernel to do this patching for usermode vDSO when
there is no guarantee of such of rest of usermode (which if was compiled with
shadow stack would have faulted before vDSO's sspush/sspopchk if ran on
pre-zimop hardware)

>
>It would be nice if a kernel could be built that would run on both
>pre-Zimop and post-Zimop hardware and be able to offer CFI to
>userspace when running on hardware with Zimop (and Zicfiss / Zicfilp)
>but agree that it is a burden.
>
>>
>> Just for sake of thought exercise, let's say Fedora 43 is first release with
>> RVA23 compatiblity (zimop and shadow stack), there is no way this and future
>> release will be able to run on pre-zimop hardware. Unless redhat is going to
>> start two different binary distribution. One for pre-zimop and one for
>> post-zimop. If that would be the case, then compiling two different kernel for
>> such two different hardware would be least of the worry.
>
>It would be one thing if there were hardware supporting
>Zimop/Zicfiss/Zicfilp readily available, but I am not aware of any

And that's the reason currently default is "No" for cfi config in kernel.
Hope is whenever we have hardware, we can start lighting up and take decision
how to proceed. I keep reiterting, door isn't closed yet but we gotta approach
the door.

>platform other than qemu to test this code. 

I have tested this with qemu in following configurations

qemu implements cfi extensions:
Kernel with cfi enable is able to host userspace with and without cfi compiled.
Kernel with cfi enable is able to host userspace with cfi but disabled (default
to zimop)
Kernel without cfi enable is able to host userspace with cfi (default to zimop)
and without cfi.

qemu doesn't implement cfi extension:
- Kernel without cfi enable is able to host userspace without cfi compiled in.
- Kernel without cfi enable hosting userspace with cfi compiled in faults in
   libc/ld on first sspush.
- Kernel with cfi enable trying to host userspace with cfi faults in libc/ld on
   first sspush.
- Kernel with cfi enable trying to host userspace without cfi faults in vDSO on
   first sspush.

Last case is the only breaking case, rest all compatibilities stories work.
In order to solve this last compatiblity story, I am fearful that we might be
adding un-necessary complexity in kernel which isn't desired because rest of
the userspace won't be signing up for that complexity of patching and making
it work with single binary.

> Since it breaks
>compatibility with hardware I am not sure anyone will be able to do
>anything with this config option and it moves the burden on to each
>distro to go in and specifically enabling it vs just making things
>work to get important security improvements if the hardware has
>support and not if it doesn't in a backwards compatible way.

I wished that shadow stack instructions came out of HINT space. But it is
what it is. Perhaps distro should give this feedback to RVI. But here we
are.

zimop is backward compatible only RVA23 onwards. That's why it's important
for distro to make a decision on this. Once they compile for RVA23 profile,
it assumed a clean break from previous hardware. Future extensions will also
take encodings out of zimop and thus I believe its better to take that decision
now with first user of zimop.

>
>>
>> Only other usecase is of a seasoned kernel developer or build your own stuff
>> in embedded environment, those users can anyways are advanced users. But it
>> forces complexity on rest of kernel. There will be more extensions taking zimop
>> encodings in future, we will end up patching vDSO and keep this complexity
>> while rest of the userspace will not be patched and will be separate binary
>> distribution (if OS distros endup distributing multiple binaries per release)
>>
>> >
>> >However, that concern should not hold up this patch series. Raise it again
>> >when the VDSO patches are posted.
>>
>> As I said earlier, these changes default cfi config to No. So whenever this
>> is selected "Yes" by a distro, they can drive such patches (if there is a real
>> need)
>
>If we did the patching we could make this config default to yes to
>that you are building a kernel that is set up to be able to offer CFI
>when running on hardware which supports it as long as you have a
>toolchain that recognizes the extensions which I think would be good
>for moving this important security feature forward.

Again, Why kernel should be doing this when rest of the userspace isn't
patchable on pre-zimop hardware (thats the only scenario patching is needed)?

Are distro's distributing different binary for with autovec and without autovec
for different kind of riscv hardware?

Giving example of Fedora 43, once it is compiled in with cfi enabling, kernel is
also compiled in with the feature. Its not like there is going to "Fedora
43_rv64gc" release. If there is going to be a "Fedora 43_rv64gc" release, it'll
be much easier to no select CFI for that release's kernel compile rather than
kernel doing patching in runtime (rest of userspace is not doing any patching)

>
>>
>> >
>> >>
>> >> thanks Deepak,
>> >>
>> >> - Paul
>> >
>> >Best - Charlie
>> >
>>
>
>Sorry for stirring the pot on this. I really appreciate your work on
>this patch series.
>
>I agree that this is a difficult call, and I could see it going either
>way but I lean towards trying to maintain the backwards compatibility
>because the hardware doesn't exist yet.
>
>Best - Charlie
>
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Florian Weimer 5 days, 5 hours ago
* Deepak Gupta:

> In case of shadow stack, it similar situation. If enabled compiler
> decides to insert sspush and sspopchk. They necessarily won't be
> prologue or epilogue but somewhere in function body as deemed fit by
> compiler, thus increasing the complexity of runtime patching.
>
> More so, here are wishing for kernel to do this patching for usermode
> vDSO when there is no guarantee of such of rest of usermode (which if
> was compiled with shadow stack would have faulted before vDSO's
> sspush/sspopchk if ran on pre-zimop hardware)

I think this capability is desirable so that you can use a distribution
kernel during CFI userspace bringup.

Thanks,
Florian
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Deepak Gupta 4 days, 14 hours ago
On Tue, Sep 30, 2025 at 11:20:32AM +0200, Florian Weimer wrote:
>* Deepak Gupta:
>
>> In case of shadow stack, it similar situation. If enabled compiler
>> decides to insert sspush and sspopchk. They necessarily won't be
>> prologue or epilogue but somewhere in function body as deemed fit by
>> compiler, thus increasing the complexity of runtime patching.
>>
>> More so, here are wishing for kernel to do this patching for usermode
>> vDSO when there is no guarantee of such of rest of usermode (which if
>> was compiled with shadow stack would have faulted before vDSO's
>> sspush/sspopchk if ran on pre-zimop hardware)
>
>I think this capability is desirable so that you can use a distribution
>kernel during CFI userspace bringup.

I didn't get it, can you elaborate more.

Why having kernel carry two vDSO (one with shadow stack and one without) would
be required to for CFI userspace bringup?

If Distro is compiling for RVA23 CONFIG_RISCV_USERCFI has to be selected yes,
kernel can have vDSO with shadow stack. Distro can light this option only when
its compiling entire distro for RVA23.

If distro is not compiling for RVA23, then anyways CONFIG_RISCV_USERCFI is by
default "N". This would simply build vDSO without shadow stack.

>
>Thanks,
>Florian
>
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Florian Weimer 3 days, 2 hours ago
* Deepak Gupta:

> On Tue, Sep 30, 2025 at 11:20:32AM +0200, Florian Weimer wrote:
>>* Deepak Gupta:
>>
>>> In case of shadow stack, it similar situation. If enabled compiler
>>> decides to insert sspush and sspopchk. They necessarily won't be
>>> prologue or epilogue but somewhere in function body as deemed fit by
>>> compiler, thus increasing the complexity of runtime patching.
>>>
>>> More so, here are wishing for kernel to do this patching for usermode
>>> vDSO when there is no guarantee of such of rest of usermode (which if
>>> was compiled with shadow stack would have faulted before vDSO's
>>> sspush/sspopchk if ran on pre-zimop hardware)
>>
>>I think this capability is desirable so that you can use a distribution
>>kernel during CFI userspace bringup.
>
> I didn't get it, can you elaborate more.
>
> Why having kernel carry two vDSO (one with shadow stack and one without) would
> be required to for CFI userspace bringup?
>
> If Distro is compiling for RVA23 CONFIG_RISCV_USERCFI has to be selected yes,
> kernel can have vDSO with shadow stack. Distro can light this option only when
> its compiling entire distro for RVA23.

I think it boils down to whether you want CFI bringup contributions from
people who do not want to or cannot build their own custom RVA23
kernels.

Another use case would be running container images with CFI on a
distribution kernel which supports pre-RVA23 hardware.

Thanks,
Florian
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Deepak Gupta 2 days, 21 hours ago
On Thu, Oct 02, 2025 at 01:45:48PM +0200, Florian Weimer wrote:
>* Deepak Gupta:
>
>> On Tue, Sep 30, 2025 at 11:20:32AM +0200, Florian Weimer wrote:
>>>* Deepak Gupta:
>>>
>>>> In case of shadow stack, it similar situation. If enabled compiler
>>>> decides to insert sspush and sspopchk. They necessarily won't be
>>>> prologue or epilogue but somewhere in function body as deemed fit by
>>>> compiler, thus increasing the complexity of runtime patching.
>>>>
>>>> More so, here are wishing for kernel to do this patching for usermode
>>>> vDSO when there is no guarantee of such of rest of usermode (which if
>>>> was compiled with shadow stack would have faulted before vDSO's
>>>> sspush/sspopchk if ran on pre-zimop hardware)
>>>
>>>I think this capability is desirable so that you can use a distribution
>>>kernel during CFI userspace bringup.
>>
>> I didn't get it, can you elaborate more.
>>
>> Why having kernel carry two vDSO (one with shadow stack and one without) would
>> be required to for CFI userspace bringup?
>>
>> If Distro is compiling for RVA23 CONFIG_RISCV_USERCFI has to be selected yes,
>> kernel can have vDSO with shadow stack. Distro can light this option only when
>> its compiling entire distro for RVA23.
>
>I think it boils down to whether you want CFI bringup contributions from
>people who do not want to or cannot build their own custom RVA23
>kernels.

How will they contribute to CFI bringup without having a CFI compiled usersapce?
If their userspace is compiled with shadow stack instructions and they can't take
this userspace to old hardware else it'll start faulting as soon as control is
given to userspace (first sspush or sspopcheck in userspace).

>
>Another use case would be running container images with CFI on a
>distribution kernel which supports pre-RVA23 hardware.

Container image with CFI will have glibc and ld (and all other userspace) also
compiled with shadow stack instructions in it. As soon as you take this
container image to a pre-RVA23 hardware, you won't even reach vDSO. It'll break
much before that, unless kernel is taking a trap on all sspush/sspopchk
instructions in prologue/epilogue of functions in userspace (glibc, ld, etc)

>
>Thanks,
>Florian
>
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Charles Mirabile 1 week, 1 day ago
Hi -

Sorry for my previous email, I realized I was mistaken...

On Fri, Sep 26, 2025 at 03:29:19PM -0400, Charles Mirabile wrote:
> Hi - 
> 
> Hoping that I got everything right with git-send-email so that this is
> delivered alright...
> 
> Wanted to jump in to head off a potential talking past one another / 
> miscommunication situation I see here.
> 
> On Wed, Sep 24, 2025 at 08:36:11AM -0600, Paul Walmsley wrote:
> > Hi,
> > 
> > On Thu, 31 Jul 2025, Deepak Gupta wrote:
> > 
> > [ ... ]
> > 
> > > vDSO related Opens (in the flux)
> > > =================================
> > > 
> > > I am listing these opens for laying out plan and what to expect in future
> > > patch sets. And of course for the sake of discussion.
> > > 
> > 
> > [ ... ]
> > 
> > > How many vDSOs
> > > ---------------
> > > Shadow stack instructions are carved out of zimop (may be operations) and if CPU
> > > doesn't implement zimop, they're illegal instructions. Kernel could be running on
> > > a CPU which may or may not implement zimop. And thus kernel will have to carry 2
> > > different vDSOs and expose the appropriate one depending on whether CPU implements
> > > zimop or not.
> > 
> > If we merge this series without this, then when CFI is enabled in the 
> > Kconfig, we'll wind up with a non-portable kernel that won't run on older 
> > hardware.  We go to great lengths to enable kernel binary portability 
> > across the presence or absence of other RISC-V extensions, and I think 
> > these CFI extensions should be no different.
> 
> That is not true, this series does not contain the VDSO changes so it can
> be merged as is.

Oops... no sorry, it looks like it does. See 19/27. I was misled by the
cover letter which said to pick that patch separately. I completely agree
that that needs to not be included if this is to be merged.

> 
> > 
> > So before considering this for merging, I'd like to see at least an 
> > attempt to implement the dual-vDSO approach (or something equivalent) 
> > where the same kernel binary with CFI enabled can run on both pre-Zimop 
> > and post-Zimop hardware, with the existing userspaces that are common 
> > today.
> 
> I agree that when the VDSO patches are submitted for inclusion they should
> be written in a way that avoids limiting the entire kernel to either
> pre-Zimop or post-Zimop hardware based on the config, but I think it
> should be quite possible to perform e.g. runtime patching of the VDSO
> to replace the Zimop instructions with nops if the config is enabled but
> the hardware does not support Zimop.
> 
> However, that concern should not hold up this patch series. Raise it again
> when the VDSO patches are posted.

@Deepak, would it be possible to just resend this without the VDSO patch?

Or to rework as I had alluded to to check for the presense of the extension
and remove the instructions from the VDSO at boot if it is not found?

> 
> > 
> > thanks Deepak,
> > 
> > - Paul
> 
> Best - Charlie
> 

Best - Charlie
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Deepak Gupta 1 week, 1 day ago
On Fri, Sep 26, 2025 at 03:52:24PM -0400, Charles Mirabile wrote:
>Hi -
>
>Sorry for my previous email, I realized I was mistaken...
>
>On Fri, Sep 26, 2025 at 03:29:19PM -0400, Charles Mirabile wrote:
>> Hi -
>>
>> Hoping that I got everything right with git-send-email so that this is
>> delivered alright...
>>
>> Wanted to jump in to head off a potential talking past one another /
>> miscommunication situation I see here.
>>
>> On Wed, Sep 24, 2025 at 08:36:11AM -0600, Paul Walmsley wrote:
>> > Hi,
>> >
>> > On Thu, 31 Jul 2025, Deepak Gupta wrote:
>> >
>> > [ ... ]
>> >
>> > > vDSO related Opens (in the flux)
>> > > =================================
>> > >
>> > > I am listing these opens for laying out plan and what to expect in future
>> > > patch sets. And of course for the sake of discussion.
>> > >
>> >
>> > [ ... ]
>> >
>> > > How many vDSOs
>> > > ---------------
>> > > Shadow stack instructions are carved out of zimop (may be operations) and if CPU
>> > > doesn't implement zimop, they're illegal instructions. Kernel could be running on
>> > > a CPU which may or may not implement zimop. And thus kernel will have to carry 2
>> > > different vDSOs and expose the appropriate one depending on whether CPU implements
>> > > zimop or not.
>> >
>> > If we merge this series without this, then when CFI is enabled in the
>> > Kconfig, we'll wind up with a non-portable kernel that won't run on older
>> > hardware.  We go to great lengths to enable kernel binary portability
>> > across the presence or absence of other RISC-V extensions, and I think
>> > these CFI extensions should be no different.
>>
>> That is not true, this series does not contain the VDSO changes so it can
>> be merged as is.
>
>Oops... no sorry, it looks like it does. See 19/27. I was misled by the
>cover letter which said to pick that patch separately. I completely agree
>that that needs to not be included if this is to be merged.

Yes I sent another email.

>
>>
>> >
>> > So before considering this for merging, I'd like to see at least an
>> > attempt to implement the dual-vDSO approach (or something equivalent)
>> > where the same kernel binary with CFI enabled can run on both pre-Zimop
>> > and post-Zimop hardware, with the existing userspaces that are common
>> > today.
>>
>> I agree that when the VDSO patches are submitted for inclusion they should
>> be written in a way that avoids limiting the entire kernel to either
>> pre-Zimop or post-Zimop hardware based on the config, but I think it
>> should be quite possible to perform e.g. runtime patching of the VDSO
>> to replace the Zimop instructions with nops if the config is enabled but
>> the hardware does not support Zimop.
>>
>> However, that concern should not hold up this patch series. Raise it again
>> when the VDSO patches are posted.
>
>@Deepak, would it be possible to just resend this without the VDSO patch?

No we can't do that because if cfi is opted yes and user enables it then an
indirect jump to vDSO function will result in a trap to supervisor and then
SIGSEGV.

We can compile vDSO without shadow stack option. That leaves vDSO as the only
object in address space of program open to code re-use gadgets because return
path is not protected with shadow stack (thus dilutes security properties)

>
>Or to rework as I had alluded to to check for the presense of the extension
>and remove the instructions from the VDSO at boot if it is not found?

I have responded to your earlier e-mail on this. TLDR is

If kernel is required to carry two different libraries with a need of patching
it in runtime, while rest of the userspace can't be  patched in runtime. Is it
worth the complexity to enforce on kernel? Because we then will be doing this
for every future extension which takes encodings form zimop space while rest
of the userspace really can't do that.


>
>>
>> >
>> > thanks Deepak,
>> >
>> > - Paul
>>
>> Best - Charlie
>>
>
>Best - Charlie
>
Re: [PATCH v19 00/27] riscv control-flow integrity for usermode
Posted by Benjamin LaHaise 2 months ago
Be advised that all emails from @rivosinc.com sent via the mailing list
are rejected by all mailing list recipients @gmail.com and any other
domains using Google's mail infrastructure.  Quite simply: only
implementing SPF is no longer sufficient for your messages to be delivered
anymore.

		-ben

On Thu, Jul 31, 2025 at 04:19:10PM -0700, Deepak Gupta wrote:
> Basics and overview
> ===================
> 
> Software with larger attack surfaces (e.g. network facing apps like databases,
> browsers or apps relying on browser runtimes) suffer from memory corruption
> issues which can be utilized by attackers to bend control flow of the program
> to eventually gain control (by making their payload executable). Attackers are
> able to perform such attacks by leveraging call-sites which rely on indirect
> calls or return sites which rely on obtaining return address from stack memory.
> 
> To mitigate such attacks, risc-v extension zicfilp enforces that all indirect
> calls must land on a landing pad instruction `lpad` else cpu will raise software
> check exception (a new cpu exception cause code on riscv).
> Similarly for return flow, risc-v extension zicfiss extends architecture with
> 
> - `sspush` instruction to push return address on a shadow stack
> - `sspopchk` instruction to pop return address from shadow stack
>   and compare with input operand (i.e. return address on stack)
> - `sspopchk` to raise software check exception if comparision above
>   was a mismatch
> - Protection mechanism using which shadow stack is not writeable via
>   regular store instructions
> 
> More information an details can be found at extensions github repo [1].
> 
> Equivalent to landing pad (zicfilp) on x86 is `ENDBRANCH` instruction in Intel
> CET [3] and branch target identification (BTI) [4] on arm.
> Similarly x86's Intel CET has shadow stack [5] and arm64 has guarded control
> stack (GCS) [6] which are very similar to risc-v's zicfiss shadow stack.
> 
> x86 and arm64 support for user mode shadow stack is already in mainline.
> 
> Kernel awareness for user control flow integrity
> ================================================
> 
> This series picks up Samuel Holland's envcfg changes [2] as well. So if those are
> being applied independently, they should be removed from this series.
> 
> Enabling:
> 
> In order to maintain compatibility and not break anything in user mode, kernel
> doesn't enable control flow integrity cpu extensions on binary by default.
> Instead exposes a prctl interface to enable, disable and lock the shadow stack
> or landing pad feature for a task. This allows userspace (loader) to enumerate
> if all objects in its address space are compiled with shadow stack and landing
> pad support and accordingly enable the feature. Additionally if a subsequent
> `dlopen` happens on a library, user mode can take a decision again to disable
> the feature (if incoming library is not compiled with support) OR terminate the
> task (if user mode policy is strict to have all objects in address space to be
> compiled with control flow integirty cpu feature). prctl to enable shadow stack
> results in allocating shadow stack from virtual memory and activating for user
> address space. x86 and arm64 are also following same direction due to similar
> reason(s).
> 
> clone/fork:
> 
> On clone and fork, cfi state for task is inherited by child. Shadow stack is
> part of virtual memory and is a writeable memory from kernel perspective
> (writeable via a restricted set of instructions aka shadow stack instructions)
> Thus kernel changes ensure that this memory is converted into read-only when
> fork/clone happens and COWed when fault is taken due to sspush, sspopchk or
> ssamoswap. In case `CLONE_VM` is specified and shadow stack is to be enabled,
> kernel will automatically allocate a shadow stack for that clone call.
> 
> map_shadow_stack:
> 
> x86 introduced `map_shadow_stack` system call to allow user space to explicitly
> map shadow stack memory in its address space. It is useful to allocate shadow
> for different contexts managed by a single thread (green threads or contexts)
> risc-v implements this system call as well.
> 
> signal management:
> 
> If shadow stack is enabled for a task, kernel performs an asynchronous control
> flow diversion to deliver the signal and eventually expects userspace to issue
> sigreturn so that original execution can be resumed. Even though resume context
> is prepared by kernel, it is in user space memory and is subject to memory
> corruption and corruption bugs can be utilized by attacker in this race window
> to perform arbitrary sigreturn and eventually bypass cfi mechanism.
> Another issue is how to ensure that cfi related state on sigcontext area is not
> trampled by legacy apps or apps compiled with old kernel headers.
> 
> In order to mitigate control-flow hijacting, kernel prepares a token and place
> it on shadow stack before signal delivery and places address of token in
> sigcontext structure. During sigreturn, kernel obtains address of token from
> sigcontext struture, reads token from shadow stack and validates it and only
> then allow sigreturn to succeed. Compatiblity issue is solved by adopting
> dynamic sigcontext management introduced for vector extension. This series
> re-factor the code little bit to allow future sigcontext management easy (as
> proposed by Andy Chiu from SiFive)
> 
> config and compilation:
> 
> Introduce a new risc-v config option `CONFIG_RISCV_USER_CFI`. Selecting this
> config option picks the kernel support for user control flow integrity. This
> optin is presented only if toolchain has shadow stack and landing pad support.
> And is on purpose guarded by toolchain support. Reason being that eventually
> vDSO also needs to be compiled in with shadow stack and landing pad support.
> vDSO compile patches are not included as of now because landing pad labeling
> scheme is yet to settle for usermode runtime.
> 
> To get more information on kernel interactions with respect to
> zicfilp and zicfiss, patch series adds documentation for
> `zicfilp` and `zicfiss` in following:
> Documentation/arch/riscv/zicfiss.rst
> Documentation/arch/riscv/zicfilp.rst
> 
> How to test this series
> =======================
> 
> Toolchain
> ---------
> $ git clone git@github.com:sifive/riscv-gnu-toolchain.git -b cfi-dev
> $ riscv-gnu-toolchain/configure --prefix=<path-to-where-to-build> --with-arch=rv64gc_zicfilp_zicfiss --enable-linux --disable-gdb  --with-extra-multilib-test="rv64gc_zicfilp_zicfiss-lp64d:-static"
> $ make -j$(nproc)
> 
> Qemu
> ----
> Get the lastest qemu
> $ cd qemu
> $ mkdir build
> $ cd build
> $ ../configure --target-list=riscv64-softmmu
> $ make -j$(nproc)
> 
> Opensbi
> -------
> $ git clone git@github.com:deepak0414/opensbi.git -b v6_cfi_spec_split_opensbi
> $ make CROSS_COMPILE=<your riscv toolchain> -j$(nproc) PLATFORM=generic
> 
> Linux
> -----
> Running defconfig is fine. CFI is enabled by default if the toolchain
> supports it.
> 
> $ make ARCH=riscv CROSS_COMPILE=<path-to-cfi-riscv-gnu-toolchain>/build/bin/riscv64-unknown-linux-gnu- -j$(nproc) defconfig
> $ make ARCH=riscv CROSS_COMPILE=<path-to-cfi-riscv-gnu-toolchain>/build/bin/riscv64-unknown-linux-gnu- -j$(nproc)
> 
> In case you're building your own rootfs using toolchain, please make sure you
> pick following patch to ensure that vDSO compiled with lpad and shadow stack.
> 
> "arch/riscv: compile vdso with landing pad"
> 
> Branch where above patch can be picked
> https://github.com/deepak0414/linux-riscv-cfi/tree/vdso_user_cfi_v6.12-rc1
> 
> Running
> -------
> 
> Modify your qemu command to have:
> -bios <path-to-cfi-opensbi>/build/platform/generic/firmware/fw_dynamic.bin
> -cpu rv64,zicfilp=true,zicfiss=true,zimop=true,zcmop=true
> 
> vDSO related Opens (in the flux)
> =================================
> 
> I am listing these opens for laying out plan and what to expect in future
> patch sets. And of course for the sake of discussion.
> 
> Shadow stack and landing pad enabling in vDSO
> ----------------------------------------------
> vDSO must have shadow stack and landing pad support compiled in for task
> to have shadow stack and landing pad support. This patch series doesn't
> enable that (yet). Enabling shadow stack support in vDSO should be
> straight forward (intend to do that in next versions of patch set). Enabling
> landing pad support in vDSO requires some collaboration with toolchain folks
> to follow a single label scheme for all object binaries. This is necessary to
> ensure that all indirect call-sites are setting correct label and target landing
> pads are decorated with same label scheme.
> 
> How many vDSOs
> ---------------
> Shadow stack instructions are carved out of zimop (may be operations) and if CPU
> doesn't implement zimop, they're illegal instructions. Kernel could be running on
> a CPU which may or may not implement zimop. And thus kernel will have to carry 2
> different vDSOs and expose the appropriate one depending on whether CPU implements
> zimop or not.
> 
> References
> ==========
> [1] - https://github.com/riscv/riscv-cfi
> [2] - https://lore.kernel.org/all/20240814081126.956287-1-samuel.holland@sifive.com/
> [3] - https://lwn.net/Articles/889475/
> [4] - https://developer.arm.com/documentation/109576/0100/Branch-Target-Identification
> [5] - https://www.intel.com/content/dam/develop/external/us/en/documents/catc17-introduction-intel-cet-844137.pdf
> [6] - https://lwn.net/Articles/940403/
> 
> To: Thomas Gleixner <tglx@linutronix.de>
> To: Ingo Molnar <mingo@redhat.com>
> To: Borislav Petkov <bp@alien8.de>
> To: Dave Hansen <dave.hansen@linux.intel.com>
> To: x86@kernel.org
> To: H. Peter Anvin <hpa@zytor.com>
> To: Andrew Morton <akpm@linux-foundation.org>
> To: Liam R. Howlett <Liam.Howlett@oracle.com>
> To: Vlastimil Babka <vbabka@suse.cz>
> To: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> To: Paul Walmsley <paul.walmsley@sifive.com>
> To: Palmer Dabbelt <palmer@dabbelt.com>
> To: Albert Ou <aou@eecs.berkeley.edu>
> To: Conor Dooley <conor@kernel.org>
> To: Rob Herring <robh@kernel.org>
> To: Krzysztof Kozlowski <krzk+dt@kernel.org>
> To: Arnd Bergmann <arnd@arndb.de>
> To: Christian Brauner <brauner@kernel.org>
> To: Peter Zijlstra <peterz@infradead.org>
> To: Oleg Nesterov <oleg@redhat.com>
> To: Eric Biederman <ebiederm@xmission.com>
> To: Kees Cook <kees@kernel.org>
> To: Jonathan Corbet <corbet@lwn.net>
> To: Shuah Khan <shuah@kernel.org>
> To: Jann Horn <jannh@google.com>
> To: Conor Dooley <conor+dt@kernel.org>
> To: Miguel Ojeda <ojeda@kernel.org>
> To: Alex Gaynor <alex.gaynor@gmail.com>
> To: Boqun Feng <boqun.feng@gmail.com>
> To: Gary Guo <gary@garyguo.net>
> To: Björn Roy Baron <bjorn3_gh@protonmail.com>
> To: Benno Lossin <benno.lossin@proton.me>
> To: Andreas Hindborg <a.hindborg@kernel.org>
> To: Alice Ryhl <aliceryhl@google.com>
> To: Trevor Gross <tmgross@umich.edu>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-mm@kvack.org
> Cc: linux-riscv@lists.infradead.org
> Cc: devicetree@vger.kernel.org
> Cc: linux-arch@vger.kernel.org
> Cc: linux-doc@vger.kernel.org
> Cc: linux-kselftest@vger.kernel.org
> Cc: alistair.francis@wdc.com
> Cc: richard.henderson@linaro.org
> Cc: jim.shu@sifive.com
> Cc: andybnac@gmail.com
> Cc: kito.cheng@sifive.com
> Cc: charlie@rivosinc.com
> Cc: atishp@rivosinc.com
> Cc: evan@rivosinc.com
> Cc: cleger@rivosinc.com
> Cc: alexghiti@rivosinc.com
> Cc: samitolvanen@google.com
> Cc: broonie@kernel.org
> Cc: rick.p.edgecombe@intel.com
> Cc: rust-for-linux@vger.kernel.org
> 
> changelog
> ---------
> v19:
> - riscv_nousercfi was `int`. changed it to unsigned long.
>   Thanks to Alex Ghiti for reporting it. It was a bug.
> - ELP is cleared on trap entry only when CONFIG_64BIT.
> - restore ssp back on return to usermode was being done
>   before `riscv_v_context_nesting_end` on trap exit path.
>   If kernel shadow stack were enabled this would result in
>   kernel operating on user shadow stack and panic (as I found
>   in my testing of kcfi patch series). So fixed that.
> 
> v18:
> - rebased on 6.16-rc1
> - uprobe handling clears ELP in sstatus image in pt_regs
> - vdso was missing shadow stack elf note for object files.
>   added that. Additional asm file for vdso needed the elf marker
>   flag. toolchain should complain if `-fcf-protection=full` and
>   marker is missing for object generated from asm file. Asked
>   toolchain folks to fix this. Although no reason to gate the merge
>   on that.
> - Split up compile options for march and fcf-protection in vdso
>   Makefile
> - CONFIG_RISCV_USER_CFI option is moved under "Kernel features" menu
>   Added `arch/riscv/configs/hardening.config` fragment which selects
>   CONFIG_RISCV_USER_CFI
> 
> v17:
> - fixed warnings due to empty macros in usercfi.h (reported by alexg)
> - fixed prefixes in commit titles reported by alexg
> - took below uprobe with fcfi v2 patch from Zong Li and squashed it with
>   "riscv/traps: Introduce software check exception and uprobe handling"
>   https://lore.kernel.org/all/20250604093403.10916-1-zong.li@sifive.com/
> 
> v16:
> - If FWFT is not implemented or returns error for shadow stack activation, then
>   no_usercfi is set to disable shadow stack. Although this should be picked up
>   by extension validation and activation. Fixed this bug for zicfilp and zicfiss
>   both. Thanks to Charlie Jenkins for reporting this.
> - If toolchain doesn't support cfi, cfi kselftest shouldn't build. Suggested by
>   Charlie Jenkins.
> - Default for CONFIG_RISCV_USER_CFI is set to no. Charlie/Atish suggested to
>   keep it off till we have more hardware availibility with RVA23 profile and
>   zimop/zcmop implemented. Else this will start breaking people's workflow
> - Includes the fix if "!RV64 and !SBI" then definitions for FWFT in
>   asm-offsets.c error.
> 
> v15:
> - Toolchain has been updated to include `-fcf-protection` flag. This
>   exists for x86 as well. Updated kernel patches to compile vDSO and
>   selftest to compile with `fcf-protection=full` flag.
> - selecting CONFIG_RISCV_USERCFI selects CONFIG_RISCV_SBI.
> - Patch to enable shadow stack for kernel wasn't hidden behind
>   CONFIG_RISCV_USERCFI and CONFIG_RISCV_SBI. fixed that.
> 
> v14:
> - rebased on top of palmer/sbi-v3. Thus dropped clement's FWFT patches
>   Updated RISCV_ISA_EXT_XXXX in hwcap and hwprobe constants.
> - Took Radim's suggestions on bitfields.
> - Placed cfi_state at the end of thread_info block so that current situation
>   is not disturbed with respect to member fields of thread_info in single
>   cacheline.
> 
> v13:
> - cpu_supports_shadow_stack/cpu_supports_indirect_br_lp_instr uses
>   riscv_has_extension_unlikely()
> - uses nops(count) to create nop slide
> - RISCV_ACQUIRE_BARRIER is not needed in `amo_user_shstk`. Removed it
> - changed ternaries to simply use implicit casting to convert to bool.
> - kernel command line allows to disable zicfilp and zicfiss independently.
>   updated kernel-parameters.txt.
> - ptrace user abi for cfi uses bitmasks instead of bitfields. Added ptrace
>   kselftest.
> - cosmetic and grammatical changes to documentation.
> 
> v12:
> - It seems like I had accidently squashed arch agnostic indirect branch
>   tracking prctl and riscv implementation of those prctls. Split them again.
> - set_shstk_status/set_indir_lp_status perform CSR writes only when CPU
>   support is available. As suggested by Zong Li.
> - Some minor clean up in kselftests as suggested by Zong Li.
> 
> v11:
> - patch "arch/riscv: compile vdso with landing pad" was unconditionally
>   selecting `_zicfilp` for vDSO compile. fixed that. Changed `lpad 1` to
>   to `lpad 0`. 
> v10:
> - dropped "mm: helper `is_shadow_stack_vma` to check shadow stack vma". This patch
>   is not that interesting to this patch series for risc-v. There are instances in
>   arch directories where VM_SHADOW_STACK flag is anyways used. Dropping this patch
>   to expedite merging in riscv tree.
> - Took suggestions from `Clement` on "riscv: zicfiss / zicfilp enumeration" to
>   validate presence of cfi based on config.
> - Added a patch for vDSO to have `lpad 0`. I had omitted this earlier to make sure
>   we add single vdso object with cfi enabled. But a vdso object with scheme of 
>   zero labeled landing pad is least common denominator and should work with all
>   objects of zero labeled as well as function-signature labeled objects.
> 
> v9:
> - rebased on master (39a803b754d5 fix braino in "9p: fix ->rename_sem exclusion")
> - dropped "mm: Introduce ARCH_HAS_USER_SHADOW_STACK" (master has it from arm64/gcs)
> - dropped "prctl: arch-agnostic prctl for shadow stack" (master has it from arm64/gcs)
> 
> v8:
> - rebased on palmer/for-next
> - dropped samuel holland's `envcfg` context switch patches.
>   they are in parlmer/for-next
>   
> v7:
> - Removed "riscv/Kconfig: enable HAVE_EXIT_THREAD for riscv"
>   Instead using `deactivate_mm` flow to clean up.
>   see here for more context
>   https://lore.kernel.org/all/20230908203655.543765-1-rick.p.edgecombe@intel.com/#t
> - Changed the header include in `kselftest`. Hopefully this fixes compile
>   issue faced by Zong Li at SiFive.
> - Cleaned up an orphaned change to `mm/mmap.c` in below patch
>   "riscv/mm : ensure PROT_WRITE leads to VM_READ | VM_WRITE"
> - Lock interfaces for shadow stack and indirect branch tracking expect arg == 0
>   Any future evolution of this interface should accordingly define how arg should
>   be setup.
> - `mm/map.c` has an instance of using `VM_SHADOW_STACK`. Fixed it to use helper
>   `is_shadow_stack_vma`.
> - Link to v6: https://lore.kernel.org/r/20241008-v5_user_cfi_series-v6-0-60d9fe073f37@rivosinc.com
> 
> v6:
> - Picked up Samuel Holland's changes as is with `envcfg` placed in
>   `thread` instead of `thread_info`
> - fixed unaligned newline escapes in kselftest
> - cleaned up messages in kselftest and included test output in commit message
> - fixed a bug in clone path reported by Zong Li
> - fixed a build issue if CONFIG_RISCV_ISA_V is not selected
>   (this was introduced due to re-factoring signal context
>   management code)
> 
> v5:
> - rebased on v6.12-rc1
> - Fixed schema related issues in device tree file
> - Fixed some of the documentation related issues in zicfilp/ss.rst
>   (style issues and added index)
> - added `SHADOW_STACK_SET_MARKER` so that implementation can define base
>   of shadow stack.
> - Fixed warnings on definitions added in usercfi.h when
>   CONFIG_RISCV_USER_CFI is not selected.
> - Adopted context header based signal handling as proposed by Andy Chiu
> - Added support for enabling kernel mode access to shadow stack using
>   FWFT
>   (https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-firmware-features.adoc)
> - Link to v5: https://lore.kernel.org/r/20241001-v5_user_cfi_series-v1-0-3ba65b6e550f@rivosinc.com
>   (Note: I had an issue in my workflow due to which version number wasn't
>   picked up correctly while sending out patches)
> 
> v4:
> - rebased on 6.11-rc6
> - envcfg: Converged with Samuel Holland's patches for envcfg management on per-
> thread basis.
> - vma_is_shadow_stack is renamed to is_vma_shadow_stack
> - picked up Mark Brown's `ARCH_HAS_USER_SHADOW_STACK` patch
> - signal context: using extended context management to maintain compatibility.
> - fixed `-Wmissing-prototypes` compiler warnings for prctl functions
> - Documentation fixes and amending typos.
> - Link to v4: https://lore.kernel.org/all/20240912231650.3740732-1-debug@rivosinc.com/
> 
> v3:
> - envcfg
>   logic to pick up base envcfg had a bug where `ENVCFG_CBZE` could have been
>   picked on per task basis, even though CPU didn't implement it. Fixed in
>    this series.
> 
> - dt-bindings
>   As suggested, split into separate commit. fixed the messaging that spec is
>   in public review
> 
> - arch_is_shadow_stack change
>   arch_is_shadow_stack changed to vma_is_shadow_stack
> 
> - hwprobe
>   zicfiss / zicfilp if present will get enumerated in hwprobe
> 
> - selftests
>   As suggested, added object and binary filenames to .gitignore
>   Selftest binary anyways need to be compiled with cfi enabled compiler which
>   will make sure that landing pad and shadow stack are enabled. Thus removed
>   separate enable/disable tests. Cleaned up tests a bit.
> 
> - Link to v3: https://lore.kernel.org/lkml/20240403234054.2020347-1-debug@rivosinc.com/
> 
> v2:
> - Using config `CONFIG_RISCV_USER_CFI`, kernel support for riscv control flow
>   integrity for user mode programs can be compiled in the kernel.
> 
> - Enabling of control flow integrity for user programs is left to user runtime
> 
> - This patch series introduces arch agnostic `prctls` to enable shadow stack
>   and indirect branch tracking. And implements them on riscv.
> 
> ---
> Changes in v19:
> - Link to v18: https://lore.kernel.org/r/20250711-v5_user_cfi_series-v18-0-a8ee62f9f38e@rivosinc.com
> 
> Changes in v18:
> - Link to v17: https://lore.kernel.org/r/20250604-v5_user_cfi_series-v17-0-4565c2cf869f@rivosinc.com
> 
> Changes in v17:
> - Link to v16: https://lore.kernel.org/r/20250522-v5_user_cfi_series-v16-0-64f61a35eee7@rivosinc.com
> 
> Changes in v16:
> - Link to v15: https://lore.kernel.org/r/20250502-v5_user_cfi_series-v15-0-914966471885@rivosinc.com
> 
> Changes in v15:
> - changelog posted just below cover letter
> - Link to v14: https://lore.kernel.org/r/20250429-v5_user_cfi_series-v14-0-5239410d012a@rivosinc.com
> 
> Changes in v14:
> 
> - changelog posted just below cover letter
> - Link to v13: https://lore.kernel.org/r/20250424-v5_user_cfi_series-v13-0-971437de586a@rivosinc.com
> 
> Changes in v13:
> - changelog posted just below cover letter
> - Link to v12: https://lore.kernel.org/r/20250314-v5_user_cfi_series-v12-0-e51202b53138@rivosinc.com
> 
> Changes in v12:
> - changelog posted just below cover letter
> - Link to v11: https://lore.kernel.org/r/20250310-v5_user_cfi_series-v11-0-86b36cbfb910@rivosinc.com
> 
> Changes in v11:
> - changelog posted just below cover letter
> - Link to v10: https://lore.kernel.org/r/20250210-v5_user_cfi_series-v10-0-163dcfa31c60@rivosinc.com
> 
> ---
> Andy Chiu (1):
>       riscv: signal: abstract header saving for setup_sigcontext
> 
> Deepak Gupta (25):
>       mm: VM_SHADOW_STACK definition for riscv
>       dt-bindings: riscv: zicfilp and zicfiss in dt-bindings (extensions.yaml)
>       riscv: zicfiss / zicfilp enumeration
>       riscv: zicfiss / zicfilp extension csr and bit definitions
>       riscv: usercfi state for task and save/restore of CSR_SSP on trap entry/exit
>       riscv/mm : ensure PROT_WRITE leads to VM_READ | VM_WRITE
>       riscv/mm: manufacture shadow stack pte
>       riscv/mm: teach pte_mkwrite to manufacture shadow stack PTEs
>       riscv/mm: write protect and shadow stack
>       riscv/mm: Implement map_shadow_stack() syscall
>       riscv/shstk: If needed allocate a new shadow stack on clone
>       riscv: Implements arch agnostic shadow stack prctls
>       prctl: arch-agnostic prctl for indirect branch tracking
>       riscv: Implements arch agnostic indirect branch tracking prctls
>       riscv/traps: Introduce software check exception and uprobe handling
>       riscv/signal: save and restore of shadow stack for signal
>       riscv/kernel: update __show_regs to print shadow stack register
>       riscv/ptrace: riscv cfi status and state via ptrace and in core files
>       riscv/hwprobe: zicfilp / zicfiss enumeration in hwprobe
>       riscv: kernel command line option to opt out of user cfi
>       riscv: enable kernel access to shadow stack memory via FWFT sbi call
>       riscv: create a config for shadow stack and landing pad instr support
>       riscv: Documentation for landing pad / indirect branch tracking
>       riscv: Documentation for shadow stack on riscv
>       kselftest/riscv: kselftest for user mode cfi
> 
> Jim Shu (1):
>       arch/riscv: compile vdso with landing pad and shadow stack note
> 
>  Documentation/admin-guide/kernel-parameters.txt    |   8 +
>  Documentation/arch/riscv/index.rst                 |   2 +
>  Documentation/arch/riscv/zicfilp.rst               | 115 +++++
>  Documentation/arch/riscv/zicfiss.rst               | 179 +++++++
>  .../devicetree/bindings/riscv/extensions.yaml      |  14 +
>  arch/riscv/Kconfig                                 |  21 +
>  arch/riscv/Makefile                                |   5 +-
>  arch/riscv/configs/hardening.config                |   4 +
>  arch/riscv/include/asm/asm-prototypes.h            |   1 +
>  arch/riscv/include/asm/assembler.h                 |  44 ++
>  arch/riscv/include/asm/cpufeature.h                |  12 +
>  arch/riscv/include/asm/csr.h                       |  16 +
>  arch/riscv/include/asm/entry-common.h              |   2 +
>  arch/riscv/include/asm/hwcap.h                     |   2 +
>  arch/riscv/include/asm/mman.h                      |  26 +
>  arch/riscv/include/asm/mmu_context.h               |   7 +
>  arch/riscv/include/asm/pgtable.h                   |  30 +-
>  arch/riscv/include/asm/processor.h                 |   1 +
>  arch/riscv/include/asm/thread_info.h               |   3 +
>  arch/riscv/include/asm/usercfi.h                   |  95 ++++
>  arch/riscv/include/asm/vector.h                    |   3 +
>  arch/riscv/include/uapi/asm/hwprobe.h              |   2 +
>  arch/riscv/include/uapi/asm/ptrace.h               |  34 ++
>  arch/riscv/include/uapi/asm/sigcontext.h           |   1 +
>  arch/riscv/kernel/Makefile                         |   1 +
>  arch/riscv/kernel/asm-offsets.c                    |  10 +
>  arch/riscv/kernel/cpufeature.c                     |  27 +
>  arch/riscv/kernel/entry.S                          |  38 ++
>  arch/riscv/kernel/head.S                           |  27 +
>  arch/riscv/kernel/process.c                        |  27 +-
>  arch/riscv/kernel/ptrace.c                         |  95 ++++
>  arch/riscv/kernel/signal.c                         | 148 +++++-
>  arch/riscv/kernel/sys_hwprobe.c                    |   2 +
>  arch/riscv/kernel/sys_riscv.c                      |  10 +
>  arch/riscv/kernel/traps.c                          |  54 ++
>  arch/riscv/kernel/usercfi.c                        | 545 +++++++++++++++++++++
>  arch/riscv/kernel/vdso/Makefile                    |  11 +-
>  arch/riscv/kernel/vdso/flush_icache.S              |   4 +
>  arch/riscv/kernel/vdso/getcpu.S                    |   4 +
>  arch/riscv/kernel/vdso/rt_sigreturn.S              |   4 +
>  arch/riscv/kernel/vdso/sys_hwprobe.S               |   4 +
>  arch/riscv/kernel/vdso/vgetrandom-chacha.S         |   5 +-
>  arch/riscv/mm/init.c                               |   2 +-
>  arch/riscv/mm/pgtable.c                            |  16 +
>  include/linux/cpu.h                                |   4 +
>  include/linux/mm.h                                 |   7 +
>  include/uapi/linux/elf.h                           |   2 +
>  include/uapi/linux/prctl.h                         |  27 +
>  kernel/sys.c                                       |  30 ++
>  tools/testing/selftests/riscv/Makefile             |   2 +-
>  tools/testing/selftests/riscv/cfi/.gitignore       |   3 +
>  tools/testing/selftests/riscv/cfi/Makefile         |  16 +
>  tools/testing/selftests/riscv/cfi/cfi_rv_test.h    |  82 ++++
>  tools/testing/selftests/riscv/cfi/riscv_cfi_test.c | 173 +++++++
>  tools/testing/selftests/riscv/cfi/shadowstack.c    | 385 +++++++++++++++
>  tools/testing/selftests/riscv/cfi/shadowstack.h    |  27 +
>  56 files changed, 2389 insertions(+), 30 deletions(-)
> ---
> base-commit: a2a05801de77ca5122fc34e3eb84d6359ef70389
> change-id: 20240930-v5_user_cfi_series-3dc332f8f5b2
> --
> - debug
> 

-- 
"Thought is the essence of where you are now."