Skip to content

Make -Zcf-protection work on RISC-V - #165215

Open
shuffle2 wants to merge 1 commit into
rust-lang:mainfrom
shuffle2:riscv-cfi-protection
Open

shuffle2 wants to merge 1 commit into
rust-lang:mainfrom
shuffle2:riscv-cfi-protection

Conversation

@shuffle2

@shuffle2 shuffle2 commented Oct 31, 2026 •

Copy link
Copy Markdown

-Zcf-protection=branch (or full) currently crashes rustc when targeting RISC-V:

rustc --target riscv64gc-unknown-none-elf --crate-type lib \
    -C target-feature=+experimental-zicfilp -Zcf-protection=full lib.rs

LLVM's RISC-V backend expects a cf-branch-label-scheme module flag whenever cf-protection-branch is set, and segfaults in RISCVAsmPrinter::emitNoteGnuProperty without it. Clang always emits the two together.

-Zcf-protection=return doesn't crash, but it also doesn't do anything: the Zicfiss shadow stack is enabled per function through the hw-shadow-stack attribute, and the cf-protection-return module flag only sets the bit in .note.gnu.property.

This PR emits the label scheme flag on RISC-V and adds hw-shadow-stack for return/full, matching what Clang does for -fcf-protection. Other targets are unaffected.

The label scheme is always unlabeled. An earlier version of this had a -Zcf-branch-label-scheme=unlabeled|func-sig option to mirror Clang's -mcf-branch-label-scheme, but I dropped it since func-sig isn't implemented in LLVM yet (the backend errors out with "the complete func-sig label scheme feature is not implemented yet", see llvm/llvm-project#111661), so the only non-default value couldn't compile anything. Clang recently made unlabeled its default as well (llvm/llvm-project#223297). The option can be added later if LLVM grows support.

With LLVM 22 the new module flag is just ignored, so there's no version check.

Dynamically linked code also needs a landing-pad-aware PLT from lld (llvm/llvm-project#145461). That's not in LLVM 23 and will be a separate backport.

This also fixes a sentence in the sanitizer docs that said ShadowCallStack uses the Zicfiss ssp register when available. It always uses gp; the hardware shadow stack only comes from hw-shadow-stack.

Tracking issue: #93754

LLVM's RISC-V backend expects a `cf-branch-label-scheme` module flag
whenever `cf-protection-branch` is set, and crashes without one. Emit it
with `unlabeled`, which is the only scheme LLVM implements.

The Zicfiss shadow stack is enabled per function through the
`hw-shadow-stack` attribute rather than by the module flag, so add that
for `-Zcf-protection=return` and `full`. Both match what Clang does for
`-fcf-protection` on RISC-V.
@rustbot

rustbot commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred in src/doc/unstable-book/src/compiler-flags/sanitizer.md

cc @rust-lang/project-exploit-mitigations, @rcvalle

Some changes occurred in src/doc/unstable-book/src/compiler-flags/cf-protection.md

cc @rust-lang/project-exploit-mitigations, @rcvalle

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 31, 2026
@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Oct 31, 2026
@rustbot

rustbot commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust Project has assigned @JonathanBrouwer (or someone else) to review your changes, you should hear from them (or someone else) within the next two weeks.

Please see the contribution instructions and our LLM policy for more information.

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 77 candidates
  • Random selection from 21 candidates

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants