ARM Permission Indirection
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
- 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