Documentation/arch/riscv/zicfilp.rst
Source file repositories/reference/linux-study-clean/Documentation/arch/riscv/zicfilp.rst
File Facts
- System
- Linux kernel
- Corpus path
Documentation/arch/riscv/zicfilp.rst- Extension
.rst- Size
- 5795 bytes
- Lines
- 138
- Domain
- Support Tooling And Documentation
- Bucket
- Documentation
- Inferred role
- Support Tooling And Documentation: documentation
- Status
- atlas-only
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
- No top-level syscall, struct, function, initcall, or export declaration detected by the generator.
Annotated Snippet
.. SPDX-License-Identifier: GPL-2.0
:Author: Deepak Gupta <debug@rivosinc.com>
:Date: 12 January 2024
====================================================
Tracking indirect control transfers on RISC-V Linux
====================================================
This document briefly describes the interface provided to userspace by Linux
to enable indirect branch tracking for user mode applications on RISC-V.
1. Feature Overview
--------------------
Memory corruption issues usually result in crashes. However, in the
hands of a creative adversary, these can result in a variety of
security issues.
Some of those security issues can be code re-use attacks, where an
adversary can use corrupt function pointers, chaining them together to
perform jump oriented programming (JOP) or call oriented programming
(COP) and thus compromise control flow integrity (CFI) of the program.
Function pointers live in read-write memory and thus are susceptible
to corruption. This can allow an adversary to control the program
counter (PC) value. On RISC-V, the zicfilp extension enforces a
restriction on such indirect control transfers:
- Indirect control transfers must land on a landing pad instruction ``lpad``.
There are two exceptions to this rule:
- rs1 = x1 or rs1 = x5, i.e. a return from a function and returns are
protected using shadow stack (see zicfiss.rst)
- rs1 = x7. On RISC-V, the compiler usually does the following to reach a
function which is beyond the offset of possible J-type instruction::
auipc x7, <imm>
jalr (x7)
This form of indirect control transfer is immutable and doesn't
rely on memory. Thus rs1=x7 is exempted from tracking and
these are considered software guarded jumps.
The ``lpad`` instruction is a pseudo-op of ``auipc rd, <imm_20bit>``
with ``rd=x0``. This is a HINT op. The ``lpad`` instruction must be
aligned on a 4 byte boundary. It compares the 20 bit immediate with
x7. If ``imm_20bit`` == 0, the CPU doesn't perform any comparison with
``x7``. If ``imm_20bit`` != 0, then ``imm_20bit`` must match ``x7``
else CPU will raise ``software check exception`` (``cause=18``) with
``*tval = 2``.
The compiler can generate a hash over function signatures and set them
up (truncated to 20 bits) in x7 at callsites. Function prologues can
have ``lpad`` instructions encoded with the same function hash. This
further reduces the number of valid program counter addresses a call
site can reach.
2. ELF and psABI
-----------------
The toolchain sets up :c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_FCFI` for
property :c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_AND` in the notes
section of the object file.
3. Linux enabling
------------------
User space programs can have multiple shared objects loaded in their
Annotation
- Atlas domain: Support Tooling And Documentation / Documentation.
- Implementation status: atlas-only.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.