Skip to content

ARM Permission Indirection

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.

Perm Meaning
0b0000 No access, Overlay applied.
0b0001 Read, Overlay applied.
0b0010 Execute, Overlay applied.
0b0011 Read and Execute, Overlay applied.
0b0100 Reserved - treated as No access, Overlay applied.
0b0101 Read and Write, Overlay applied.
0b0110 Read, Write and Execute, Overlay applied.
0b0111 Read, Write and Execute, Overlay applied.
0b1000 Read, Overlay not applied.
0b1001 Read, GCS Read and GCS Write, Overlay not applied.
0b1010 Read and Execute, Overlay not applied.
0b1011 Reserved - treated as No access, Overlay not applied.
0b1100 Read and Write, Overlay not applied.
0b1101 Reserved - treated as No access, Overlay not applied.
0b1110 Read, Write and Execute, Overlay not applied.
0b1111 Reserved - 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