Try   HackMD

Pointer Authentication and Memory Tagging

All about ARM security extensions

Pointer Authentication

Background

  • Code reuse attacks: ROP,JOP
  • Memory protection largely prevents code injection
  • Various mitigations today
    • e.g. ASLR, execute-only memory, CFI, canaries, pointer mangling, shadow stacks
    • difficult to integrate
    • non-trivial performance / code size impact
    • inhibit debugging

ROP protection example

backwards compatible ver.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More β†’

normal ver.
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More β†’

Theory

  • instructions to sign and authenticate pointers
    • architecture provides mechanism, not policy
  • Pointer Authentication Code (PAC)
    • authentication metadata stored within pointer
    • no additional space required
    • derived from:
      • A pointer value
      • A 64-bit context value
      • A 128-bit secret key
        Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More β†’
  • Key:
    • 128-bit value inhibit prediction / forging of PACs
    • APIAKEY can be used, but not read/written at EL0 (userspace)
    • The kernel maintains an APIAKey value for each process (shared by all threads within), which is initialised to a random value at exec() time.
    • limited risk of disclosure / modification
    • five separate keys:
      • two for executable (instruction) pointers
      • two for data
      • one "general" key
  • Pointer Memory layout:
    • 7 bits with 48-bit VA with tagging
      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More β†’
    • 15 bits with 48-bit VA without tagging
      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More β†’
  • Operations:
    • sign
      • PAC* instructions sign pointers with PACs
      • Result is not a usable pointer
        Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More β†’
    • authenticate
      • AUT* instructions authenticate PACs
      • If PAC matches, result is the original pointer
      • If PAC doesn’t match, result is an invalid pointer β†’ faults upon use
        Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More β†’
    • strip
      • XPAC* instructions strip PACs
      • Result is the original pointer
      • No authentication is performed
        Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More β†’

Mechanism

  • Insert a PAC into a pointer
  • Strip a PAC from a pointer
  • Authenticate strip a PAC from a pointer
    • If authentication succeeds, the code is removed, yielding the original pointer
    • If authentication fails, bits are set in the pointer such that it is guaranteed
      to cause a fault if used

Usage

  • Optional ARMv8.3-A extension
  • Detects illicit modification of pointers (and data structures)
  • Backwards compatible subset
    • binaries using some features can run on any ARMv8-A CPU (without protection)
    • distributions only need one set of binaries

Memory Tagging

  • "Hardware-ASAN on steroids"
    • RAM overhead: 3%-5%
    • CPU overhead: (hoping for) low-single-digit %
  • AArch64 only because it need Top Byte Ignore(TBI)
    • In 64-bit, general-purpose registers(GPR64) make the most significant 16 bits of an address must be all 0xFFFF or 0x0000
    • the top eight bits, that is [63:56] of the Virtual Address are ignored by the processor when tagged addressing support is enabled
  • Two types of tags
    • Every aligned 16 bytes of memory have a 4-bit tag stored separately
    • Every pointer has a 4-bit tag stored in the top byte

Mechanism

  • Allocation:
    • Align allocations by 16
    • Choose a 4-bit tag (random is ok)
    • Tag the pointer
    • Tag the memory (optionally initialize it at no extra cost)
  • Deallocation:
    • Re-tag the memory with a different tag
  • To use tagging with heap allocations only the allocator needs to make use of the new instructions, the rest of the code only performs standard LDR/STR

Detect

  • Heap-buffer-overflow

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More β†’

  • Heap-use-after-free

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More β†’

Kernel ABI and HWCAPs

  1. On AArch64 the TCR_EL1.TBI0 bit is set by default(CPU Feature Register)
  2. All syscalls need to accept any valid tagged pointer, and it should work as the untagged pointer.
  3. UB for invalid tagged pointer
  4. Documentation/arm64/tagged-address-abi.rst

MTE Enabled Kernel Interface

  1. built on top of the newly introduced Aarch64 Tagged Address ABI
  2. The Kernel exposes a new mmap()/mprotect() flag: PROT_MTE
  3. Kernel supports both the exception types: Precise and Imprecise
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More β†’
  4. How does it work?
    • Memory allocator, which ultimately invokes mmap()
    • with a special flag, PROT_MTE, the reserved memory has tagging effects enabled
    • The allocator tags the memory and returns to the application a tagged pointer
      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More β†’

Compiler perspective(challenges)

  • slide1
  • C family has suck memory safety
    • Use-after-free / buffer-overflow / uninitialized memory
    • High and Critical ratio in bugs
    • AddressSanitizer (ASAN) is not enough
      • Hard to use in production
      • Not a security mitigation
  • Tagging heap objects
    • CPU: malloc/free become O(size) operations
  • Tagging stack objects
    • CPU: function prologue becomes O(frame size)
    • Stack size: local variables aligned by 16
    • Code size: extra instructions per function entry/exit
    • Register pressure: local variables have unique tags, not as simple as [SP, #offset]
  • Malloc zero-fill
  • Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More β†’
  • Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More β†’
  • reduce the overhead

existing implementations

  • SPARC ADI
    • HW ASAN
    • 4-bit tags per 64-bytes of memory
    • high RAM overhead due to 64-byte alignment
  • LLVM HWASAN
    • Software implementation similar to ASAN (LLVM ToT)
    • 8-bit tags per 16-bytes of memory
    • AArch64-only (uses top-byte-ignore)
    • Overhead: 6% RAM, 2x CPU, 2x code size