Support RISC-V Control Flow Integrity Extensions#3
Open
Conversation
kito-cheng
reviewed
May 28, 2025
Member
kito-cheng
left a comment
There was a problem hiding this comment.
could you rename most variable about lp to lp_unlabeled since we will have lp_func_sig in future.
25abf21 to
78c1733
Compare
7fae5b2 to
b752f71
Compare
kito-cheng
reviewed
Jun 16, 2025
| This tunable is specific to aarch64. | ||
| @end deftp | ||
|
|
||
| @deftp Tunable glibc.cpu.riscv_cfi_lp |
Member
There was a problem hiding this comment.
Suggested change
| @deftp Tunable glibc.cpu.riscv_cfi_lp | |
| @deftp Tunable glibc.cpu.riscv_cfi_unlabeled_lp |
|
|
||
| struct dl_riscv_feature_control | ||
| { | ||
| enum dl_riscv_cfi_control lp : 2; |
Member
There was a problem hiding this comment.
Suggested change
| enum dl_riscv_cfi_control lp : 2; | |
| enum dl_riscv_cfi_control unlabeled_lp : 2; |
6cb15b3 to
fbbc3b0
Compare
33dc279 to
337c0b3
Compare
0a049e1 to
6d561c5
Compare
Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
Add GNU properties used by RISC-V CFI extensions (zicfilp/zicfiss)
Landing pads, instructions for setting the label value as well as alignment directives are inserted at where they should be. Frame offsets for floating point registers in _dl_runtime_resolve are also adjusted because now t2 has to be saved onto the stack. Co-authored-by: Hau Hsu <hau.hsu@sifive.com> Co-authored-by: Kito Cheng <kito.cheng@sifive.com>
Member l_riscv_feature_1_and is added to struct link_map, which stores the feature_1_and property information for each object. New global _dl_riscv_feature_1 will be used to store what features are finally enabled for this process.
These operations are for setting/retrieving/locking the status of the landing pad and the shadow stack extensions.
For static binaries, CFI are enabled inside ARCH_SETUP_TLS, with a macro to enable the shadow stack to prevent underflowing the shadow stack on return, and with a function _dl_cfi_setup_features to enable landing pad. It scans backward of the program header to find the PT_GNU_PROPERTY note first, then enable CFI features corresponding to the feature bits. Co-authored-by: Deepak Gupta <debug@rivosinc.com>
For dynamic binaries, CFI features are parsed from GNU properties, store in to GLRO(dl_riscv_feature_1) and later enabled in RTLD_START. Co-authored-by: Deepak Gupta <debug@rivosinc.com>
dl_riscv_feature_control is a structure with each member represents a feature configuration. At this time it's only used by CFI features. Each cfi feature is a 2-bit enum, which could be [on|off|permissive], these values decide whether a new legacy object should be blocked while loaded dynamically, and could be controled by glibc tunables.
Since longjmp to a previous setjmp'ed state could change the stack frame and involves stack frame unwinding, shadow stacks is also required to be unwinded. The unwinding is implemented according to the zicfiss spec by increasing the ssp by a page size (4K) at most, to prevent from accidentally point to another legal shadow stack page after the adjustment.
Switching between different ucontexts involves two cases, one is both sharing a same shadow stack, which requires a unwinding, and the other is both using a different shadow stack, which require a stack switch using shadow stack restore token. By storing shadow stack in ucontext_t and TLS, we can tell the difference and perform the following action.
This patch adds support for shadow stack and landing pad to the ucontext library, shadow stack switches are protected by a shadow stack restore token which will be validated during the switch. Co-authored-by: Nia Su <nia.su@sifive.com>
jaidTw
pushed a commit
that referenced
this pull request
Feb 6, 2026
On x86-64, when glibc is configured with --enable-stack-protector=all
and compiled with -Os, ld.so crashes very early:
(gdb) r --direct
Starting program: /export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/string/test-memswap --direct
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f41b0a in bsearch (__key=__key@entry=0x7fffffffda28,
__base=__base@entry=0x7ffff7fca140 <intel_02_known>,
__nmemb=__nmemb@entry=68, __size=__size@entry=8,
__compar=__compar@entry=0x7ffff7f3b691 <intel_02_known_compare>)
at ../bits/stdlib-bsearch.h:22
22 {
(gdb) disass
Dump of assembler code for function bsearch:
0x00007ffff7f41af0 <+0>: push %r15
0x00007ffff7f41af2 <+2>: mov %rcx,%r15
0x00007ffff7f41af5 <+5>: push %r14
0x00007ffff7f41af7 <+7>: push %r13
0x00007ffff7f41af9 <+9>: mov %rsi,%r13
0x00007ffff7f41afc <+12>: push %r12
0x00007ffff7f41afe <+14>: mov %rdi,%r12
0x00007ffff7f41b01 <+17>: push %rbp
0x00007ffff7f41b02 <+18>: mov %rdx,%rbp
0x00007ffff7f41b05 <+21>: push %rbx
0x00007ffff7f41b06 <+22>: sub $0x18,%rsp
=> 0x00007ffff7f41b0a <+26>: mov %fs:0x28,%r14
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ We can't use stack protector at this point.
0x00007ffff7f41b13 <+35>: mov %r14,0x8(%rsp)
0x00007ffff7f41b18 <+40>: mov %r8,%r14
0x00007ffff7f41b1b <+43>: test %rbp,%rbp
0x00007ffff7f41b1e <+46>: je 0x7ffff7f41b48 <bsearch+88>
0x00007ffff7f41b20 <+48>: mov %rbp,%rbx
0x00007ffff7f41b23 <+51>: mov %r12,%rdi
0x00007ffff7f41b26 <+54>: shr $1,%rbx
0x00007ffff7f41b29 <+57>: imul %r15,%rbx
0x00007ffff7f41b2d <+61>: add %r13,%rbx
0x00007ffff7f41b30 <+64>: mov %rbx,%rsi
(gdb) bt
#0 0x00007ffff7f41b0a in bsearch (__key=__key@entry=0x7fffffffda28,
__base=__base@entry=0x7ffff7fca140 <intel_02_known>,
__nmemb=__nmemb@entry=68, __size=__size@entry=8,
__compar=__compar@entry=0x7ffff7f3b691 <intel_02_known_compare>)
at ../bits/stdlib-bsearch.h:22
#1 0x00007ffff7f3c1be in intel_check_word (name=188, value=1979933440,
has_level_2=has_level_2@entry=0x7fffffffda7f,
no_level_2_or_3=no_level_2_or_3@entry=0x7fffffffda7e,
cpu_features=<optimized out>) at ../sysdeps/x86/dl-cacheinfo.h:217
#2 0x00007ffff7f3c29f in handle_intel (name=name@entry=188,
cpu_features=<optimized out>) at ../sysdeps/x86/dl-cacheinfo.h:279
#3 0x00007ffff7f3ccf9 in dl_init_cacheinfo (cpu_features=<optimized out>)
at ../sysdeps/x86/dl-cacheinfo.h:852
riscvarchive#4 init_cpu_features (cpu_features=<optimized out>)
at ../sysdeps/x86/cpu-features.c:1153
riscvarchive#5 0x00007ffff7f3d6f9 in __libc_start_main_impl (main=0x7ffff7f396dc <main>,
argc=2, argv=0x7fffffffdbe8, init=<optimized out>, fini=<optimized out>,
rtld_fini=0x0, stack_end=0x7fffffffdbd8) at ../csu/libc-start.c:269
riscvarchive#6 0x00007ffff7f39901 in _start () at ../sysdeps/x86_64/start.S:115
(gdb)
The problem is that since __USE_EXTERN_INLINES isn't defined with -Os,
the inline bsearch in <bits/stdlib-bsearch.h> isn't available and the
external bsearch is compiled with stack protector. Include
<bits/stdlib-bsearch.h> in dl-cacheinfo.h fixed BZ #33374.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Sam James <sam@gentoo.org>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.