qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/24] riscv support for control flow integrity extensions
@ 2024-07-25 23:45 Deepak Gupta
  2024-07-25 23:45 ` [PATCH 01/24] target/riscv: Add zicfilp extension Deepak Gupta
                   ` (23 more replies)
  0 siblings, 24 replies; 25+ messages in thread
From: Deepak Gupta @ 2024-07-25 23:45 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, jim.shu, andy.chiu, jesse.huang,
	kito.cheng
  Cc: palmer, Alistair.Francis, laurent, bmeng.cn, liwei1518, dbarboza,
	zhiwei_liu, Deepak Gupta

Control flow integrity extensions (`zicfilp` and `zicfiss`) [1] for risc-v
are ratified. `zicfilp` protects forward control flow i.e. indirect function
call sites while `zicfiss` protects return control flow i.e. return from
functions which have spilled return addresses on stack.

This patchset is based on recent master with patch series from LIU (alibaba)
[4] which enables `zimop` and `zcmop` support in qemu. `zicfiss` has a dependency
on `zimop` and `zcmop`.

zicfilp
-------

On a very high level `zicfilp` extends risc-v architecture by introducing a
landing pad instruction `lpad` which must be target for every indirect branch
except when
       - rs1 == x1 || x5 (a return from a function)
       - rs1 == x7 (sw guarded branch)

If `lpad` is not present, cpu will raise software check exception (cause=18)
, introduced in privileged spec version 1.13. To track `expected landing pad`
state on every indirect branch, a new state is introduced in cpu `elp` short
for expected landing pad status and can be spilled into *status register if
a trap occurs between indirect branch and target instruction. `lpad` instr
is carved out of HINT space `auipc rd` with `rd==x0` and can have 20 bit
immediate (label_20bit) encoded in it. After an indirect branch lands on
`lpad` instruction, cpu performs following checks:

  -- If label_20bit == 0, no further check are performed.
  -- If label_20bit != 0, cpu evaluates (label_20bit == x7_upper_20bit)
     If above expression is evaluated to be false, cpu raises sw check
     exception.

Software can implement more finer-grained control flow using label mechanism
defined in `zicfilp` by ensuring x7 has appropriate label setup prior to
indirect call and thus further restraining call sites target locations.

zicfiss
-------

On a very high level `zicfiss` extends risc-v architecture by providing a
separate stack (called shadow stack) to store return addresses. Shadow stack
can be protected using a reserved PTE encoding (PTE.W=1, PTE.R=0, PTE.X=0).
Only shadow stack instructions can perform stores on shadow stack memory while
regular stores on such memory result in access faults. Shadow stack memory can
be read by regular load instructions. A new unprivileged csr `CSR_SSP` is
introduced which holds pointer to shadow stack for the execution environment.
To store return addresses on shadow stack, `sspush x1/x5` instruction is added.
`sspopchk x1/x5` instruction pops from top of shadow stack and compares it with
`x1/x5` and if there is a mismatch, cpu raises a software check exception.

riscv-gnu-toolchain changes [2] are required to test these changes on qemu-user
or on full blown linux guest using qemu-system. In order to test under qemu-system,
one will require relevant linux changes as well. I've tested linux (6.8) based on
current patches [3] and booted a rootfs compiled with cfi enabled toolchain to shell.
There're still some work going on to make it work with VDSO and multi-label scheme.
But none of those work is gate for these patches.

I would like to express my sincere thanks to all the community members in helping out.
Special shout out and acknowledgement to kito cheng, andy chiu, jim shu and jesse huang
from SiFive.

[1] - https://github.com/riscv/riscv-cfi
[2] - https://github.com/sifive/riscv-gnu-toolchain/tree/cfi-dev
[3] - https://lore.kernel.org/all/20240403234054.2020347-1-debug@rivosinc.com/
[4] - https://lore.kernel.org/all/20240709113652.1239-1-zhiwei_liu@linux.alibaba.com/#t


Deepak Gupta (24):
  target/riscv: Add zicfilp extension
  target/riscv: Introduce elp state and enabling controls for zicfilp
  target/riscv: save and restore elp state on priv transitions
  target/riscv: additional code information for sw check
  target/riscv: tracking indirect branches (fcfi) for zicfilp
  target/riscv: zicfilp `lpad` impl and branch tracking
  disas/riscv: enabled `lpad` disassembly
  linux-user/syscall: introduce prctl for indirect branch tracking
  linux-user/riscv: implement indirect branch tracking prctls
  target/riscv: Add zicfiss extension
  target/riscv: introduce ssp and enabling controls for zicfiss
  target/riscv: tb flag for shadow stack  instructions
  target/riscv: implement zicfiss instructions
  target/riscv: compressed encodings for sspush and sspopchk
  target/riscv: mmu changes for zicfiss shadow stack protection
  target/riscv: shadow stack mmu index for shadow stack instructions
  linux-user/syscall: introduce prctl for shadow stack enable/disable
  linux-user/riscv: setup/teardown zicfiss shadow stack for qemu-user
  disas/riscv: enable disassembly for zicfiss instructions
  disas/riscv: enable disassembly for compressed sspush/sspopchk
  target/riscv: add trace-hooks for each case of sw-check exception
  linux-user: permit RISC-V CFI dynamic entry in VDSO
  linux-user: Add RISC-V zicfilp support in VDSO
  linux-user/riscv: Adding zicfiss/lp extension in hwprobe syscall

 disas/riscv.c                           |  71 +++++++++-
 disas/riscv.h                           |   4 +
 linux-user/gen-vdso-elfn.c.inc          |   7 +
 linux-user/riscv/cpu_loop.c             |  50 +++++++
 linux-user/riscv/target_cpu.h           |   7 +
 linux-user/riscv/target_prctl.h         |  70 ++++++++++
 linux-user/riscv/vdso-64.so             | Bin 3944 -> 4128 bytes
 linux-user/riscv/vdso.S                 |  50 +++++++
 linux-user/syscall.c                    |  40 ++++++
 target/riscv/cpu.c                      |  21 +++
 target/riscv/cpu.h                      |  28 ++++
 target/riscv/cpu_bits.h                 |  23 ++++
 target/riscv/cpu_cfg.h                  |   2 +
 target/riscv/cpu_helper.c               | 166 +++++++++++++++++++++++-
 target/riscv/cpu_user.h                 |   1 +
 target/riscv/csr.c                      | 106 +++++++++++++++
 target/riscv/helper.h                   |   6 +
 target/riscv/insn16.decode              |   4 +
 target/riscv/insn32.decode              |  23 +++-
 target/riscv/insn_trans/trans_rva.c.inc |  55 ++++++++
 target/riscv/insn_trans/trans_rvi.c.inc |  52 ++++++++
 target/riscv/internals.h                |   4 +
 target/riscv/op_helper.c                |  63 +++++++++
 target/riscv/pmp.c                      |   5 +
 target/riscv/pmp.h                      |   3 +-
 target/riscv/tcg/tcg-cpu.c              |  20 +++
 target/riscv/trace-events               |   6 +
 target/riscv/translate.c                |  80 ++++++++++++
 28 files changed, 959 insertions(+), 8 deletions(-)

-- 
2.44.0



^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2024-07-25 23:50 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-25 23:45 [PATCH 00/24] riscv support for control flow integrity extensions Deepak Gupta
2024-07-25 23:45 ` [PATCH 01/24] target/riscv: Add zicfilp extension Deepak Gupta
2024-07-25 23:45 ` [PATCH 02/24] target/riscv: Introduce elp state and enabling controls for zicfilp Deepak Gupta
2024-07-25 23:45 ` [PATCH 03/24] target/riscv: save and restore elp state on priv transitions Deepak Gupta
2024-07-25 23:45 ` [PATCH 04/24] target/riscv: additional code information for sw check Deepak Gupta
2024-07-25 23:45 ` [PATCH 05/24] target/riscv: tracking indirect branches (fcfi) for zicfilp Deepak Gupta
2024-07-25 23:45 ` [PATCH 06/24] target/riscv: zicfilp `lpad` impl and branch tracking Deepak Gupta
2024-07-25 23:45 ` [PATCH 07/24] disas/riscv: enabled `lpad` disassembly Deepak Gupta
2024-07-25 23:45 ` [PATCH 08/24] linux-user/syscall: introduce prctl for indirect branch tracking Deepak Gupta
2024-07-25 23:45 ` [PATCH 09/24] linux-user/riscv: implement indirect branch tracking prctls Deepak Gupta
2024-07-25 23:45 ` [PATCH 10/24] target/riscv: Add zicfiss extension Deepak Gupta
2024-07-25 23:46 ` [PATCH 11/24] target/riscv: introduce ssp and enabling controls for zicfiss Deepak Gupta
2024-07-25 23:46 ` [PATCH 12/24] target/riscv: tb flag for shadow stack instructions Deepak Gupta
2024-07-25 23:46 ` [PATCH 13/24] target/riscv: implement zicfiss instructions Deepak Gupta
2024-07-25 23:46 ` [PATCH 14/24] target/riscv: compressed encodings for sspush and sspopchk Deepak Gupta
2024-07-25 23:46 ` [PATCH 15/24] target/riscv: mmu changes for zicfiss shadow stack protection Deepak Gupta
2024-07-25 23:46 ` [PATCH 16/24] target/riscv: shadow stack mmu index for shadow stack instructions Deepak Gupta
2024-07-25 23:46 ` [PATCH 17/24] linux-user/syscall: introduce prctl for shadow stack enable/disable Deepak Gupta
2024-07-25 23:46 ` [PATCH 18/24] linux-user/riscv: setup/teardown zicfiss shadow stack for qemu-user Deepak Gupta
2024-07-25 23:46 ` [PATCH 19/24] disas/riscv: enable disassembly for zicfiss instructions Deepak Gupta
2024-07-25 23:46 ` [PATCH 20/24] disas/riscv: enable disassembly for compressed sspush/sspopchk Deepak Gupta
2024-07-25 23:46 ` [PATCH 21/24] target/riscv: add trace-hooks for each case of sw-check exception Deepak Gupta
2024-07-25 23:46 ` [PATCH 22/24] linux-user: permit RISC-V CFI dynamic entry in VDSO Deepak Gupta
2024-07-25 23:46 ` [PATCH 23/24] linux-user: Add RISC-V zicfilp support " Deepak Gupta
2024-07-25 23:46 ` [PATCH 24/24] linux-user/riscv: Adding zicfiss/lp extension in hwprobe syscall Deepak Gupta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).