BRL: Branch Landing for RISC-V CFI
- Branch Landing (BRL) is a framework that enforces forward-edge control-flow integrity by validating source authorization at protected landing sites.
- It replaces fixed-capacity tag checks with Bloom filter membership queries, providing constant-time verification independent of authorized source size.
- BRL integrates two lightweight ISA extensions and a dedicated state register, ensuring secure and configurable source-domain restrictions for indirect branches.
Branch Landing (BRL) is a landing-based forward-edge control-flow integrity (CFI) framework for RISC-V that enforces source-aware authorization at indirect control-flow targets by replacing fixed-capacity tag checks with Bloom filter membership queries. It introduces two lightweight ISA extensions, bld and brl, together with a dedicated architectural state register, BRState, so that each protected landing site can validate whether the incoming source Section Identifier (SID) belongs to its statically authorized source set with fixed-probe latency independent of the number of authorized sources under a chosen filter configuration (Wu et al., 25 Apr 2026).
1. Security problem and design objective
BRL is designed for forward-edge control-flow hijacking, especially Jump-Oriented Programming (JOP), function-pointer corruption, virtual function call hijacking, and dispatcher-based gadget chains such as jump tables and computed gotos (Wu et al., 25 Apr 2026). Its starting point is what the paper characterizes as a source-authorization gap in existing forward-edge mechanisms.
Coarse landing-only schemes ensure that indirect branches land on marked landing instructions, but they do not constrain which call site may jump to a given landing site. Type-based CFI narrows the target set by function signature, yet all call sites with the same signature remain in one equivalence class. Tag-based hardware CFI is more expressive, but a fixed-width register limits how many legitimate sources can be represented simultaneously for a target. BRL targets all three limitations at once: per-target source-domain authorization, no fixed-capacity bound on the number of authorized sources, and constant-time hardware checks whose latency does not scale with the size of the authorized-source set (Wu et al., 25 Apr 2026).
The mechanism is explicitly forward-edge only. Backward edges still require a separate defense, such as a shadow stack. Within that scope, BRL aims to guarantee that every indirect transfer reaching a protected landing site is preceded by a legitimate bld, carries a source SID that belongs to the target’s statically computed authorization set, and consumes that authorization state exactly once (Wu et al., 25 Apr 2026).
2. Architectural model and enforcement semantics
BRL partitions code into sections and assigns each section a Section Identifier. The section granularity is configurable: function-level, basic-block-level, coarser module-level groupings, or custom groupings via annotations are all supported by the same mechanism (Wu et al., 25 Apr 2026). This configurability is central, because it lets BRL encode policies ranging from type-based authorization to CFG-derived authorization without changing the ISA interface.
Authorization state is propagated through a dedicated CSR, BRState, with two fields: BRState.valid and BRState.sid. The SID field uses 31 bits, so up to distinct sections can be represented. At user level, only bld and brl update BRState; ordinary stores and generic CSR writes cannot modify it, modulo privileged operations (Wu et al., 25 Apr 2026).
The source-side instruction is bld SID_{\mathrm{src}}. It is inserted immediately before each indirect branch and atomically writes the source SID into BRState.sid while setting BRState.valid = 1. The target-side instruction is brl SID_T, placed at each protected landing site. Its behavior is: check BRState.valid; if the bit is clear, raise a control-flow protection fault; otherwise interpret SID_T as an index into read-only metadata, fetch the Bloom filter descriptor for the landing site, test membership of BRState.sid, and either continue execution after clearing BRState.valid or raise a control-flow protection fault if membership fails (Wu et al., 25 Apr 2026).
This single-use semantics is security-critical. A valid source authorization cannot be replayed across multiple transfers, and a direct jump into a protected landing site without a preceding bld fails because BRState.valid == 0 at brl execution (Wu et al., 25 Apr 2026). The threat model further assumes arbitrary memory write capability by the adversary, but excludes modification of executable code pages, BRL metadata in .rodata, and direct user-level manipulation of BRState (Wu et al., 25 Apr 2026).
3. Bloom filters, authorization sets, and policy expressiveness
For each landing site , BRL defines an authorized source set
Instead of storing that set explicitly, BRL encodes it as a per-target Bloom filter in read-only memory (Wu et al., 25 Apr 2026). The target-side brl instruction performs a membership query rather than a tag-equality check. This is the main design departure from prior hardware CFI based on fixed-size tag registers.
The Bloom filter parameters are the usual , with false-positive probability
BRL uses double hashing,
so only two base hashes are computed and the remaining probes are derived (Wu et al., 25 Apr 2026). The paper states that no false negatives occur, while false positives remain possible and are tuned to be very rare. In the implementation, a fixed filter size is chosen to keep across benchmarks, and no false positives were observed in evaluation (Wu et al., 25 Apr 2026).
The same machinery supports multiple policy regimes. At function-level granularity, BRL-Func assigns one SID per function and uses type-based authorization. At basic-block-level granularity, BRL-CFG assigns one SID per basic block and derives AllowedSources(T) from the CFG, thereby shrinking equivalence classes when functions share the same signature but are not all legitimate sources for a target (Wu et al., 25 Apr 2026).
| Configuration | Policy basis | Aggregate outcome |
|---|---|---|
| BRL-Func | Function-level SIDs, type-based authorization | Mean runtime overhead 0.210% under brl3; mean .text growth 0.46%; average equivalence class size 1.96 |
| BRL-CFG | Basic-block-level SIDs, CFG-derived authorization | Mean runtime overhead 0.421% under brl3; mean .text growth 0.52%; average equivalence class size 1.32 |
Across 81 benchmarks, BRL-CFG reduces the average equivalence class size by 32.5% relative to BRL-Func, while the maximum equivalence class remains 9 in both cases (Wu et al., 25 Apr 2026). This suggests that BRL’s main gain is not merely target marking, but a finer source-domain restriction under the same hardware mechanism.
4. Compiler pipeline, metadata layout, and system integration
BRL is implemented in the LLVM RISC-V backend and evaluated in the Spike ISA simulator extended with bld and brl (Wu et al., 25 Apr 2026). The compiler identifies indirect branch sources and landing sites, assigns SIDs according to the chosen granularity, constructs AllowedSources(T) either from function signatures or from interprocedural CFG and pointer analysis, emits Bloom filters and descriptors in .rodata, and inserts bld SID_{\mathrm{src}} before each indirect branch and brl SID_T at each protected landing site (Wu et al., 25 Apr 2026).
The ABI remains otherwise unchanged. Indirect calls are still jalr, returns are still jalr x0, ra, 0, and BRL simply decorates forward-edge transfers with source and landing instrumentation (Wu et al., 25 Apr 2026). This matters because BRL is meant as a focused enforcement mechanism rather than a full redesign of the call/return convention.
The metadata layout consists of Bloom filter bit arrays plus a descriptor table indexed by target SID. Each descriptor supplies at least the base address and size of the corresponding filter. The paper places both descriptors and filters in read-only sections protected by OS page permissions (Wu et al., 25 Apr 2026). On the operating-system side, BRL requires text and .rodata to remain read-only, BRState to be saved and restored across context switches, and a policy for clearing or preserving BRState across traps and interrupts. Clearing on traps is described as fail-closed behavior (Wu et al., 25 Apr 2026).
The current prototype assumes whole-program compilation and does not fully address dynamic linking or JIT-generated code. Supporting those cases would require runtime SID assignment and dynamic metadata generation or update (Wu et al., 25 Apr 2026). For out-of-order cores, the paper notes that bld should update BRState only at commit, and brl should consume it at commit as well, so that speculative instructions squashed from the reorder buffer do not violate single-use semantics. A full RTL design is left for future work (Wu et al., 25 Apr 2026).
5. Evaluation and empirical characteristics
The evaluation uses 81 BEEBS benchmarks compiled with the LLVM RISC-V backend at -O2 and executed on Spike under a weighted-cycle model where ALU operations and bld cost 1 cycle, taken branches cost 2 cycles, load/store cost 3 cycles, ecall costs 10 cycles, and brl is modeled at 3, 5, or 10 cycles for brl3, brl5, and brl10, respectively (Wu et al., 25 Apr 2026).
Under the brl3 model, mean runtime overhead is 0.210% for BRL-Func and 0.421% for BRL-CFG; medians are 0.013% and 0.014%, and maxima are 3.752% and 10.743%, respectively (Wu et al., 25 Apr 2026). Under brl5, mean overhead rises to 0.331% and 0.651%; under the conservative brl10 model, to 0.633% and 1.228% (Wu et al., 25 Apr 2026). The notable outlier is cover under BRL-CFG, with 10.74% at brl3, 16.12% at brl5, and 29.57% at brl10, attributed in the paper to three large switch tables and many CFG-protected targets (Wu et al., 25 Apr 2026).
Code size growth in .text is also small: BRL-Func has mean 0.46% and median 0.50%, while BRL-CFG has mean 0.52% and median 0.37% (Wu et al., 25 Apr 2026). Metadata overhead appears mainly in .rodata: Bloom filters and descriptor tables average about 86 bytes per benchmark for BRL-Func, and BRL-CFG has median metadata size around 264 bytes, with mean 4.15% of total binary size skewed by cover (Wu et al., 25 Apr 2026).
The security-side evaluation reports zero fail events across all 81 benchmarks, both policy configurations, and all brl latency models: every legitimate execution path passed all brl checks (Wu et al., 25 Apr 2026). BRL-CFG also protects more targets on average than BRL-Func, with mean protected targets 4.0 versus 2.3, reflecting finer-grained instrumentation (Wu et al., 25 Apr 2026). The paper further states that no false positives were observed across all benchmarks (Wu et al., 25 Apr 2026).
Compared with Bratter, a tag-based hardware CFI scheme discussed in the paper, BRL-CFG has much lower mean overhead than the reported 5.99% for Bratter’s combined enforcement and less than half of Bratter’s reported code size overhead of about 1.20% (Wu et al., 25 Apr 2026). The paper attributes this to the shift from fixed-slot tag equality to set membership in memory-backed Bloom filters.
6. Position in the CFI landscape, limitations, and implications
BRL occupies a specific point in the forward-edge CFI design space. Relative to CET/IBT-like landing-marker schemes, it is source-aware rather than merely landing-aware. Relative to type-based systems such as FineIBT, Clang CFI, and LLVM-CFI, it can reproduce type-based authorization through BRL-Func while also supporting CFG-derived restrictions through BRL-CFG under the same ISA mechanism. Relative to tag-based hardware CFI such as Bratter, it removes the hard limit imposed by a small tag register and replaces equality against one of a few slots with membership in an arbitrarily large authorized-source set whose capacity scales with filter size in memory (Wu et al., 25 Apr 2026).
The paper characterizes BRL as the first RISC-V proposal to combine source-aware authorization, arbitrary-size authorized-source sets, constant-time verification via Bloom filters, and policy agnosticism between type-based and CFG-derived authorization (Wu et al., 25 Apr 2026). A plausible implication is that BRL’s main conceptual contribution is not only low overhead, but a reformulation of hardware CFI checking as set membership rather than tag matching.
Its limitations remain explicit. BRL protects only forward edges; it assumes integrity of code pages and metadata in .rodata; Bloom filters admit false positives in principle; it does not address microarchitectural side channels; it relies on correct OS handling of BRState; and its current prototype does not support dynamic linking, shared libraries, or JIT-generated code (Wu et al., 25 Apr 2026). The paper therefore frames future work around backward-edge protection, richer policy generators, runtime SID allocation for dynamic code, and cycle-accurate RTL implementations with descriptor caches and optimized hash units (Wu et al., 25 Apr 2026).
Within those assumptions, BRL presents a hardware-software co-designed model of forward-edge CFI in which authorization is attached to landing sites, parameterized by compiler-chosen code sections, and enforced through Bloom filter membership queries with fixed probe count. That design makes source precision configurable, keeps the ISA surface minimal, and avoids the fixed-capacity bottleneck that constrains prior tag-based schemes (Wu et al., 25 Apr 2026).