ARM Permission Indirection

3 minute read

Published:

In 2022, ARM introduced a new way to control memory permissions. Instead of directly encoding the permission in the Translation Table Entry (TTE), fields in the TTEs are used to index into an array of permissions specified in a register. This indirection provides greater flexibility, greater encoding density and enables the representation of new permissions.

ARM Translation Table

Let’s first review the traditional ARM translation table format.

 63                52 52    48 47                x x-1                2
----------------------------------------------------------------------------
|  Upper attributes  |  RES0  |   Address[47:x]   |  Lower attributes  |...|
----------------------------------------------------------------------------
  • Permissions are encoded within translation table descriptors (attributes)
  • Any changes to permissions introduce performance penalties (mprotect and TLB flush)

Permission Indirection

ARM Permission Indirection

  • Permission indirection specifies each table descriptor with two indexes pointing to respective permission values: one base and another overlay.
  • Base represents the maximum permission the memory region can hold, while overlay is a further restriction (AND operation).
  • Base is cacheable in TLB, while overlay is not.

Base and Overlay Register

Each register contains 16 perms. Each perm is encoded by 4 bits.

PermMeaning
0b0000No access, Overlay applied.
0b0001Read, Overlay applied.
0b0010Execute, Overlay applied.
0b0011Read and Execute, Overlay applied.
0b0100Reserved - treated as No access, Overlay applied.
0b0101Read and Write, Overlay applied.
0b0110Read, Write and Execute, Overlay applied.
0b0111Read, Write and Execute, Overlay applied.
0b1000Read, Overlay not applied.
0b1001Read, GCS Read and GCS Write, Overlay not applied.
0b1010Read and Execute, Overlay not applied.
0b1011Reserved - treated as No access, Overlay not applied.
0b1100Read and Write, Overlay not applied.
0b1101Reserved - treated as No access, Overlay not applied.
0b1110Read, Write and Execute, Overlay not applied.
0b1111Reserved - treated as No access, Overlay not applied.

Example

Take JIT (running at EL0) as a use case.

A JIT might be allocated a page that was permitted by the operating system to be write-able or executable. The OS does the following:

  • Allocates a permissions index in the Permission Indirection Register (PIR_ELx). In this example, the OS selects index 3.
  • Sets the permission that index 3 in the PIR_ELx represents to “Read and Write, Overlay applied”, by setting the index’s bits to 0b0101.
  • Sets the PIIndex field in the TTDs of the memory locations in that range to 0b0011 (3).

The JIT could then control, with the Overlays, whether the page was currently writeable or executable. In this sense, the OS does the following:

  • Allocates a permissions overlay index in the Permission Overlay Register (POR_ELx). In this example, the OS selects index 6.
  • Sets the permission that index 6 in the POR_ELx represents to “Read only”, by setting index 6’s bits to 0b0001.

Research Directions

Possible Changes to Kernel:

  • PIR and POR will be saved and restored during the context switch (PIR and POR may be accessible from the main memory)
  • More frequent occurrences of permission changes (compared to mprotect)

research directions:

  • Program analysis
    • higher permission can be considered as a bug (violation of the principle of least permission)
    • permission misconfiguration
  • Protect PIR and POR (in-memory value)
    • ARM CCA
  • Side channel
  • Extend permissions

Reference

Arm A-Profile Architecture Developments 2022

AArch64 Kernel Page Tables - Wenbo Shen

Permission indirection and permission overlay extensions