Skip to content

Control-Flow Integrity Instructions

Summary

Control-Flow Integrity Instructions Summary (Informative)

Mnemonic Brief description
Marks a valid destination for an enforced indirect control transfer.
Atomically restores the complete CFI supervisor-state record.
Saves the complete CFI supervisor-state record.
Installs an authenticated resident continuation without return-record memory traffic.
Materializes an authenticated near-return record and transfers control.
Materializes an authenticated long-return record and transfers to a new CS:PC.
Authenticates a long-return record and restores CS:PC.
Authenticates and consumes a near continuation.

Control-Flow Integrity Model

The combined LKH:LKL value selects the CFI context. Zero is unconfigured: protected call and return instructions raise INVALID_CONTROL_TRANSITION before operand or stack access, while ordinary indirect transfers do not require a landing marker. A nonzero key permits protected instructions and requires every taken indirect JMP or call-family target to begin with CFILAND. Direct transfers do not perform the landing check.

PCALL and PRET use a 16-byte ordinary-stack record containing a continuation PC and a nonzero 63-bit PA. PLCALL and PLRET use a 24-byte record containing a continuation PC, continuation CS, and PA. FPCALL stores its authenticated continuation in LPC:LPA while reserving the same 16-byte stack footprint without return-record memory traffic. Fast calls validate the exact SP subtraction without probing or accessing the reserved return-record range, and resident returns validate the corresponding SP addition. PRET authenticates either source before target validation; PLRET has no resident form.

Every PA authenticates the complete near or long continuation, uses distinct near and long domains, and binds the continuation to its post-allocation SS:SP. Changing the key invalidates prior tags, so software changes it only after discarding or making unreachable every outstanding protected continuation. The construction and serialization are implementation-defined, must generate nonzero tags, and must provide no greater than one chance in \(2^{63}-1\) of accepting a chosen forgery per independent attempt. A construction must remain stable across every supported processor migration and suspend/resume of the same architectural context. Any additional privilege, address-space, or execution-context inputs must have the same stability, or software must install a new key after discarding outstanding protected continuations. Same-depth temporal replay and return-target confidentiality are not provided.

An active resident link prevents every taken child call. The violation is detected before target or stack access and raises INVALID_CONTROL_TRANSITION. A false CALLcc is unaffected. RET may deliberately consume a protected resident continuation without authentication and is therefore outside the protected ABI; protected code uses PRET or PLRET.

The well-formed pairs are CALL or FCALL with RET, PCALL or FPCALL with PRET, LCALL with LRET, and PLCALL with PLRET. CALL followed by PRET applies the ordinary protected-record load and authentication rules. A materialized PCALL followed by RET consumes only the continuation word and leaves the PA word on the stack; a resident FPCALL followed by RET restores the 16-byte footprint without authenticating PA. Selecting an unprotected return for a protected continuation opts out of return integrity. The protected-return guarantee therefore assumes trusted code generation and executable-code integrity preserve the selected protected return path.

Compiler output uses CALL and RET by default. FCALL is valid only for an activation that executes no taken child call before its RET, and the protected forms are selected only when the compiler enables the CFI extension. Stack alignment and stack-argument placement remain ABI responsibilities. Unwind metadata distinguishes resident from materialized return state and identifies the applicable stack footprint.

Setjmp and longjmp facilities, language exceptions, coroutines, and user-level context switches use the decomposed base and CFI context interfaces to preserve the applicable resident and key state; they do not assume whole-context atomicity. An event-entry stub remains call-free until it has saved the interrupted resident state and executed CLRLINK. If the CFI context may change, it also snapshots the key before that change. After restoring an active resident image, the stub executes ERET without an intervening taken call. Supervisor-origin, nested, and non-maskable events follow the same ordering.