Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Thu, 15 Feb 2024 08:29:15 -0500
From: "Stefan O'Rear" <>
To: "Rich Felker" <>,,
 "Markus Wichmann" <>
Cc: enh <>
Subject: Re: PAC/BTI Support on aarch64

On Tue, Feb 13, 2024, at 9:19 PM, Rich Felker wrote:
> What is the situation on x86? Does it use the same kind of per-page
> enforcement mode, or is it only global, requiring disabling it if any
> DSO lacks support? Is the endbr64 opcode a guaranteed-safe nop on
> older ISA levels, or does it need to be conditional?

The situation for hardware control flow hardening on risc-v is two
in-development extensions:

Zicfilp (landing pads) provides a 4-byte instruction which marks valid
targets for indirect jumps and calls, written `lpad LABEL`.  This is
an *architectural NOP at all ISA levels*.  Enforcement is
process-global, not per-page.

Indirect jumps can be exempted from landing pad depending on which
register is used for the address; this is expected to be used if the
address is obtained from read-only memory or an auipc instruction, so
jump tables do not use landing pads, nor are landing pads needed after
direct calls regardless of length.  A function which is not a visible
symbol and does not have its address taken does not need a landing pad.

The ABI function return is a member of the set of indirect jumps
which bypass landing pad checks, so no landing pads are needed at the
return sites of ABI function calls.  Zicfilp intentionally does not
provide any protection against ROP, a different extension must be used
to protect return addresses.

Landing pads have a 20-bit label which is expected to be used for a
function type signature, catching function type confusion events.
The hashing scheme used to generate the label from the call signature
has not yet been decided.  The call signature must be placed in the
x7/t2 register prior to an indirect jump.  The immediate layout is
such that indirect jump sites can use a single lui instruction with
a matching 20-bit immediate.  Landing pads do not check x7/t2 if
reached by a direct jump, so there is no need to initialize it prior
to a direct jump.  A `lpad 0` matches any incoming type signature.

Zicfiss (shadow stacks) provides a new shadow stack pointer register
and shadow stack memory which cannot be modified using ordinary stores.
Unlike GCS and SHSTK, the shadow stack is never accessed automatically,
"sspush ra" and "sspopchk ra" instructions must be added to the prologue
and epilogue of functions which spill their return address to the stack.
These instructions are NOPs if the shadow stack is disabled at runtime,
but are *not architectural NOPs* and will trap if executed on current

Also unlike GCS and SHSTK, the Zicfiss `ssp` register can be read and
written from user mode using dedicated instructions, so no special
mechanism is used for shadow stack switching.

To my knowledge, nothing analogous to PAC is under development.

Both shadow stacks and landing pads are enabled by bits in the senvcfg
register, and are exposed via a prctl.  The shadow stack prctl is being
developed as an architecture-independent API, which provides some form
of automatic allocation and deallocation of shadow stacks for threads.
I believe the current strategy for marking CFI support in binaries is
an ELF note similar to the x86 approach, but have not checked this part
in detail.


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.