[PATCH v2 00/14] Support RISC-V Control Flow Integrifty (CFI)
Jesse Huang
jesse.huang@sifive.com
Fri Jul 11 13:52:41 GMT 2025
This patch series adds support for the new RISC-V Control Flow Integrity (CFI)
extensions, i.e. Zicfilp and Zicfiss, as described in the following sections
of the RISC-V Instruction Set Manual:
- Volume I, Chapter 33
- Volume II, Chapter 22
Our implementation largely refers to the existing x86 CET code, and we would
like to thank the developers for their work.
Summary of Changes
------------------
1) New Option for the Build System
A new '--enable-cfi' configure option is introduced to control whether
CFI-related features are enabled. It appends the '-fcf-protection=full'
compiler flag to all source files.
2) Adjustment to Assembly Code
While compiler automatically do the job for C source files, assembly files
and routines are requiring manual modifications
- Insert GNU property notes and landing pad, label setting instructions
into assembly files and routines
- Replace indirect branches with software-guarded branches where applicable
- Extend setjmp/longjmp to support for the shadow stack by appending the
shadow stack pointer (SSP) to the jump buffer [1], and handling the
save/restore/unwinding logic
3) Parse GNU Property Notes and Setup the Environment
The loader scans the GNU_PROPERTY_RISCV_FEATURE_1_AND note and parses the
bits specified by the binary to determine the required CFI features, it
then performs checks on all dependencies, and uses new prctl operations
to call to the kernel to do the setup work.
4) Add Tunables for Overriding Runtime Behavior
Two new tunables are introduced:
- glibc.cpu.riscv_cfi_lp
- glibc.cpu.riscv_cfi_ss
These control landing pad and shadow stack behavior at runtime,
respectively. Each accepts 'on|permissive|off' for its value, which is
same as x86.
5. Store shadow stack information in TLS to support ucontext
We make the following structure changes to support the ucontext library
- A new helper function `__allocate_shadow_stack` to map a new shadow stack
Shadow stack size for the new context is based on an estimation from the
runtime stack size, which is same to the implementation of x86.
- Store ssp and shadow stack base marker in TLS
- Shrink the _SIGSET_NWORDS from 1024 to 896 for RISC-V to make two 8-byte
slots for storing ssp and shadow stack base in ucontext_t
Differences from V1
--------------------
- The new option '--enable-cfi' gets a descrition in install.texi and an entry
in NEWS
- Update prctl numbers of landing pad
- Re-implement ucontext using shadow stack restore token techniques
- Change makecontext to use the `map_shadow_stack` syscall
ABI Breakage Notes
--------------------
[1] SSP is appended at the end of 'struct __jmp_buf_internal_tag'.
Thanks,
Jesse Huang
Jesse Huang (14):
riscv: Add --enable-cfi option for controlling cfi features
riscv/cfi: Setup necessary options for enable-cfi option
riscv: Add GNU property definitions for RISC-V CFI
riscv: Adjust assembly routines to support landing pad
riscv: Introduce feature variables for holding RISC-V GNU properties
riscv/cfi: Add prctl definitions for RISC-V CFI
riscv/cfi: Enable CFI on static binaries
riscv/cfi: Enable CFI on dynamic binaries
riscv/cfi: introduce tunables for CFI features
riscv/cfi: Adjust setjmp/longjmp for shadow stack to work
riscv/cfi: Support locking/disabling CFI and move OS depedent code
riscv/cfi: Store shadow stack information in TLS and ucontext_t
riscv/cfi: Add __allocate_shadow_stack for mapping new shadow stack
riscv/cfi: Support ucontext under CFI
INSTALL | 13 +
NEWS | 3 +
configure | 12 +
configure.ac | 6 +
elf/elf.h | 5 +
manual/install.texi | 12 +
manual/tunables.texi | 22 ++
sysdeps/riscv/Makefile | 13 +-
sysdeps/riscv/__longjmp.S | 29 ++
sysdeps/riscv/bits/setjmp.h | 4 +
sysdeps/riscv/cpu-features.c | 46 +++
sysdeps/riscv/cpu-tunables.c | 50 +++
sysdeps/riscv/crti.S | 4 +
sysdeps/riscv/crtn.S | 4 +
sysdeps/riscv/dl-cfi.c | 317 ++++++++++++++++++
sysdeps/riscv/dl-get-cpu-features.c | 27 ++
sysdeps/riscv/dl-machine.h | 35 ++
sysdeps/riscv/dl-procruntime.c | 77 +++++
sysdeps/riscv/dl-prop.h | 74 ++++
sysdeps/riscv/dl-trampoline.S | 61 ++--
sysdeps/riscv/dl-tunables.list | 27 ++
sysdeps/riscv/feature-control.h | 42 +++
sysdeps/riscv/features-offsets.sym | 5 +
sysdeps/riscv/ldsodefs.h | 1 +
sysdeps/riscv/libc-start.c | 31 ++
sysdeps/riscv/libc-start.h | 95 ++++++
sysdeps/riscv/link_map.h | 22 ++
sysdeps/riscv/multiarch/memcpy_noalignment.S | 4 +
sysdeps/riscv/nptl/Makefile | 1 +
sysdeps/riscv/nptl/tcb-offsets.sym | 5 +
sysdeps/riscv/nptl/tls.h | 2 +
sysdeps/riscv/preconfigure | 2 +
sysdeps/riscv/preconfigure.ac | 1 +
sysdeps/riscv/setjmp.S | 13 +
sysdeps/riscv/start.S | 10 +
sysdeps/unix/sysv/linux/riscv/Makefile | 1 +
.../sysv/linux/riscv/allocate-shadow-stack.c | 55 +++
.../sysv/linux/riscv/allocate-shadow-stack.h | 24 ++
sysdeps/unix/sysv/linux/riscv/bits/mman.h | 30 ++
.../sysv/linux/riscv/bits/types/__sigset_t.h | 13 +
sysdeps/unix/sysv/linux/riscv/clone.S | 2 +
sysdeps/unix/sysv/linux/riscv/dl-cfi.h | 115 +++++++
sysdeps/unix/sysv/linux/riscv/getcontext.S | 20 ++
.../unix/sysv/linux/riscv/include/asm/prctl.h | 48 +++
sysdeps/unix/sysv/linux/riscv/makecontext.c | 18 +
sysdeps/unix/sysv/linux/riscv/setcontext.S | 67 ++++
sysdeps/unix/sysv/linux/riscv/swapcontext.S | 77 ++++-
sysdeps/unix/sysv/linux/riscv/sys/ucontext.h | 7 +-
sysdeps/unix/sysv/linux/riscv/sysdep.S | 1 +
sysdeps/unix/sysv/linux/riscv/sysdep.h | 73 ++++
sysdeps/unix/sysv/linux/riscv/ucontext_i.sym | 2 +
sysdeps/unix/sysv/linux/riscv/vfork.S | 1 +
52 files changed, 1606 insertions(+), 23 deletions(-)
create mode 100644 sysdeps/riscv/cpu-features.c
create mode 100644 sysdeps/riscv/cpu-tunables.c
create mode 100644 sysdeps/riscv/crti.S
create mode 100644 sysdeps/riscv/crtn.S
create mode 100644 sysdeps/riscv/dl-cfi.c
create mode 100644 sysdeps/riscv/dl-get-cpu-features.c
create mode 100644 sysdeps/riscv/dl-procruntime.c
create mode 100644 sysdeps/riscv/dl-prop.h
create mode 100644 sysdeps/riscv/dl-tunables.list
create mode 100644 sysdeps/riscv/feature-control.h
create mode 100644 sysdeps/riscv/features-offsets.sym
create mode 100644 sysdeps/riscv/libc-start.c
create mode 100644 sysdeps/riscv/libc-start.h
create mode 100644 sysdeps/riscv/link_map.h
create mode 100644 sysdeps/riscv/nptl/Makefile
create mode 100644 sysdeps/riscv/nptl/tcb-offsets.sym
create mode 100644 sysdeps/unix/sysv/linux/riscv/allocate-shadow-stack.c
create mode 100644 sysdeps/unix/sysv/linux/riscv/allocate-shadow-stack.h
create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/mman.h
create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/types/__sigset_t.h
create mode 100644 sysdeps/unix/sysv/linux/riscv/dl-cfi.h
create mode 100644 sysdeps/unix/sysv/linux/riscv/include/asm/prctl.h
--
2.39.3
More information about the Libc-alpha
mailing list