iBoot uses to load the kernel and kernel extensions. After startup is complete, the memory controller denies writes to the protected physical memory region. The Application Processor’s Memory Management Unit (MMU) is configured to help prevent mapping privileged code from physical memory outside the protected memory region and to help prevent writeable mappings of physical memory within the kernel memory region.
To prevent reconfiguration, the hardware used to enable KIP is locked after the boot process is complete.
Starting with the Apple A11 Bionic and S3 SoCs, a new hardware primitive was introduced. This primitive, Fast Permission Restrictions, includes a CPU register that quickly restricts permissions per thread. With Fast Permission Restrictions (also known as APRR registers), supported operating systems can remove execute permissions from memory without the overhead of a system call and a page table walk or flush. These registers provide one more level of mitigation for attacks from the web, particularly for code compiled at runtime (just-in-time compiled)—because memory can’t be effectively executed at the same time it’s being read from and written to.
Coprocessor firmware handles many critical system tasks—for example, the Secure Enclave, the image sensor processor, and the motion coprocessor. Therefore its security is a key part of the security of the overall system. To prevent modification of coprocessor firmware, Apple uses a mechanism called System Coprocessor Integrity Protection (SCIP).
SCIP works much like Kernel Integrity Protection (KIP): At boot time, iBoot loads each coprocessor’s firmware into a protected memory region, one that’s reserved and separate from the KIP region. iBoot configures each coprocessor’s memory unit to help prevent:
Executable mappings outside its part of the protected memory region
Writeable mappings inside its part of the protected memory region
Also at boot time, to configure SCIP for the Secure Enclave, the Secure Enclave operating system is used. After the boot process is complete, the hardware used to enable SCIP is locked. This is designed to prevent reconfiguration.
Pointer Authentication Codes (PACs) are used to protect against exploitation of memory corruption bugs. System software and built-in apps use PAC to help prevent modification of function pointers and return addresses (code pointers). PAC uses five secret 128-bit values to sign kernel instructions and data, and each user space process has its own B keys. Items are salted and signed as indicated below.
Item
Key
Salt
Function Return Address
IB
Storage address
Function Pointers
IA
0
Block Invocation Function
Objective-C Method Cache
Storage address + Class + Selector
C++ V-Table Entries
Storage address + Hash (mangled method name)
Computed Goto Label
Hash (function name)
Kernel Thread State
GA
•
User Thread State Registers
C++ V-Table Pointers
DA
The signature value is stored in the unused padding bits at the top of the 64-bit pointer. The signature is verified before use, and the padding is restored to help ensure a functioning pointer address. Failure to verify results in an abort. This verification increases the difficulty of many attacks, such as a return-oriented programming (ROP) attack, which attempts to trick the device into executing existing code maliciously by manipulating function return addresses stored on the stack.
Page Protection Layer (PPL) in iOS, iPadOS, watchOS, and visionOS is designed to prevent user space code from being modified after code signature verification is complete. Building on Kernel Integrity Protection and Fast Permission Restrictions, PPL manages the page table permission overrides to make sure only the PPL can alter protected pages containing user code and page tables. The system provides a massive reduction in attack surface by supporting systemwide code integrity enforcement, even in the face of a compromised kernel. This protection isn’t offered in macOS because PPL is only applicable on systems where all executed code must be signed.
Secure Page Table Monitor (SPTM) and Trusted Execution Monitor (TXM) on iOS, iPadOS, macOS, and visionOS are designed to work together to help protect page tables for both user and kernel processes against modification, even when attackers have kernel write capabilities and can bypass control flow protections. SPTM does this by utilizing a higher privilege level than the kernel, and utilizing the lower privileged TXM to actually enforce the policies that govern code execution. This system is designed so that a TXM compromise doesn’t automatically translate to an SPTM bypass due to this privilege separation and the governing of trust between them. In the A15 or later and M2 or later SOCs, SPTM (in combination with TXM) replaces the PPL, providing a smaller attack surface that doesn’t rely on trust of the kernel, even during early boot. SPTM relies on new silicon primitives that are an evolution of the Fast Permission Restrictions that PPL utilizes, and are available only on the processors listed in the table above.