[PATCH v2 00/14] Support RISC-V Control Flow Integrifty (CFI)

Jesse Huang jesse.huang@sifive.com
Wed Jul 23 09:12:25 GMT 2025


Hi Henrich,

Thanks for your question.
For dynamic binaries, the loader performs a check on all dependencies
listed in link_map, and CFI features (SS, LP) will only be enabled
respectively only if property notes present in all of the dependencies.
I have summarized the possible combinations and their behavior here.

1) Binary w/o CFI
No compatibility problem

2) Binary w/ CFI + dependency w/ CFI
CFI will be enabled and should be no problem

3) Binary w/ CFI + dynamic loading library w/o CFI
a. If the mode is always-on (default), dlopen will fail.
b. If the mode is permissive (can be set by glibc tunables),
   CFI will be disabled

4) Binary w/ CFI + dependency w/o CFI
CFI will not be enabled because of the dependency check won't pass

The only case that causes problem is attempting to execute shadow stack
instructions on a RVA20 machine, in this case they will be illegal
instructions due to lacking the support of Zimop/Zcmop, but this is
unlikely to happen.

On Tue, Jul 22, 2025 at 4:54 PM Heinrich Schuchardt <
heinrich.schuchardt@canonical.com> wrote:

> On 11.07.25 15:52, Jesse Huang wrote:
> > 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
> >
>
> Hello Jesse,
>
> On riscv64 we must expect that both RVA20 and RVA23 exist. Some of it
> compiled with support with shadow stack some without.
>
> For example maintainers of flatpaks and snaps cannot be expected to
> maintain multiple versions of their packages.
>
> For distros treating support for control flow integrity as a completely
> new architecture is not an attractive solution.
>
> Could you, please, describe how your patch series will ensure the
> interoperability of RVA20 and RVA23 code and of code compiled with and
> without shadow stack.
>
> Best regards
>
> Heinrich
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20250723/ae235286/attachment-0001.htm>


More information about the Libc-alpha mailing list