Skip to content

AD2039: PeEnableArmPAC

Summary

Property Value
ID AD2039
Name PeEnableArmPAC
Category Security
Severity Warning
Applies to PE (Windows ARM64)

Description

ARM64 PE binaries should enable Pointer Authentication Code (PAC) to protect return addresses and function pointers from corruption.

How It Works

The rule checks for PAC enablement:

  1. PAC-related instructions in code (PACIA, AUTIA, etc.)
  2. ARM64 PE header flags
  3. Compiler indicators for PAC usage

Why This Matters

PAC provides hardware-accelerated protection against ROP and other control-flow attacks on ARM64 systems.

How PAC Works

Function entry:
  PACIASP         ; Sign return address with key + SP

Stack:
  [Signed Return Address]  ; Contains cryptographic signature

Function exit:
  AUTIASP         ; Verify signature
  RET             ; Only reached if signature valid

PAC Key Types

Key Purpose
A-key Code pointers (default)
B-key Alternate code pointers
DA/DB Data pointers
GA Generic authentication

Security Benefits

Attack PAC Protection
ROP Return address authenticated
JOP Function pointers protected
Stack corruption Signed values detect tampering
Heap overflow Data pointer auth available

Windows on ARM64

Feature Support
Hardware Qualcomm Snapdragon, Apple M1+
OS Windows 11 ARM64
Compiler MSVC, Clang

Performance Considerations

PAC uses dedicated CPU instructions with minimal overhead:

Metric Impact
Runtime overhead <1% typical
Code size increase ~2-4% (PAC instructions)
Memory overhead None
Hardware support Required (ARMv8.3+)

Why overhead is minimal: - PACIA/AUTIA are single-cycle instructions on modern ARM cores - No memory accesses required for signing/verification - No branch misprediction penalties

Compatibility notes: - Binaries with PAC work on non-PAC hardware (instructions become NOPs) - Mixing PAC and non-PAC code is safe - No performance penalty on older hardware (just no protection)

Resolution

Enable PAC for ARM64 Windows builds:

# Clang
clang --target=aarch64-pc-windows-msvc -mbranch-protection=pac-ret program.c

# MSVC (when supported)
cl /guard:pac program.c

CMake Configuration

if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
    add_compile_options(-mbranch-protection=pac-ret)
endif()