(CVE-2024-27791) Apple PMP Firmware Out-of-Bounds Write via ApplePMPv2 writeDashboard
CVE: CVE-2024-27791
Affected Versions: iOS and iPadOS before 16.7.5 and before 17.3; macOS Monterey before 12.7.3; macOS Ventura before 13.6.4; macOS Sonoma before 14.3; tvOS before 17.3
CVSS3.1: 7.1 (High) — CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H
Summary
| Product | Apple PMP Firmware (ApplePMPv2) |
|---|---|
| Vendor | Apple |
| Severity | High — an app may be able to corrupt co-processor memory |
| Affected Versions | iOS/iPadOS < 16.7.5, < 17.3; macOS Monterey < 12.7.3; macOS Ventura < 13.6.4; macOS Sonoma < 14.3; tvOS < 17.3 |
| Tested Versions | macOS 13.3 beta3 (Mac Studio); iOS 16.4 latest beta |
| CVE Identifier | CVE-2024-27791 |
| CVE Description | An app may be able to corrupt coprocessor memory due to improper memory buffer operations; addressed via improved validation |
| CWE Classification(s) | CWE-119: Improper Restriction of Operations within Memory Buffer Bounds |
CVSS3.1 Scoring System
Base Score: 7.1 (High)
Vector String: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H
| Metric | Value |
|---|---|
| Attack Vector (AV) | Local |
| Attack Complexity (AC) | Low |
| Privileges Required (PR) | None |
| User Interaction (UI) | Required |
| Scope (S) | Unchanged |
| Confidentiality (C) | None |
| Integrity (I) | High |
| Availability (A) | High |
Product Background
The Power Management Processor (PMP) is a co-processor present in Apple Silicon devices, visible in the device tree at pmp@8EC00000. It communicates with the Application Processor (AP) via the RTBuddyV2 mailbox interface. The AP-side IOService driver is ApplePMPv2, which exposes user client methods that allow privileged processes to interact with the PMP firmware:
+-o pmp@8EC00000 <class AppleARMIODevice>
+-o AppleASCWrapV4
+-o iop-pmp-nub <class AppleA7IOPNub>
+-o RTBuddyV2 <class RTBuddyV2>
+-o ApplePMPFirmware <class ApplePMPFirmware>
+-o PMPEndpoint1 <class RTBuddyEndpointService>
+-o ApplePMPv2 <class ApplePMPv2>
Technical Details
ApplePMPv2UserClient::externalMethods exposes writeDashboard to user clients. The call chain is:
ApplePMPv2UserClient::externalMethods
→ ApplePMPv2UserClient::writeDashboard
→ ApplePMPv2::writeDashboard
Inside ApplePMPv2::writeDashboard, a user-controlled channel_idx is used to index into the PMP’s shared memory region. The bounds check only verifies that channel_idx does not exceed 383 (8 * 383 = 3064 bytes), but fails to account for the full range of values that can corrupt adjacent co-processor memory:
__int64 __fastcall ApplePMPv2::writeDashboard(ApplePMPv2 *this,
unsigned int channel_idx, __int64 write_value)
{
__int64 ret;
AppleA7IOPNub *iop_nub;
OSObject *base_addr;
ret = 0xE00002BCLL;
iop_nub = (AppleA7IOPNub *)*((_QWORD *)this + 23);
if ( iop_nub )
{
base_addr = (*(__int64 (__fastcall **)(AppleA7IOPNub *))
(*(_QWORD *)iop_nub->copyProperty_1))(iop_nub);
if ( (*(__int64 (__fastcall **)(_QWORD))
(*(_QWORD *)iop_nub->copyProperty_2))(iop_nub)
<= (unsigned __int64)(8 * channel_idx) ) // channel_idx must be <= 383
{
return 0xE00002C2LL;
}
else
{
ret = 0LL;
*((_QWORD *)&base_addr->__vftable + channel_idx) = write_value;
}
}
return ret;
}
Different channel_idx values trigger different behaviour on the PMP co-processor side:
- Channel 0 — causes a PMP panic (PTD abort)
- Channel 0xf8 — causes a Data Abort with
r22/r23registers controlled by user-supplied data, as shown in the panic log below - Channels 0xf9–0xff — cause a PMP SError (
Exception class=0x2f) with full register context and backtrace - Other channels — can cause
ApplePMGRto panic
Channel 0xf8 Data Abort, showing attacker-controlled register values (r22=0x414141414e4243ff, r23=0x4141414000000000):
panic(cpu 0 caller 0xfffffe0030476540): PMP DATA ABORT
pc=0x0000000001024bd4 Exception class=0x25 (Data Abort taken without a change
in Exception level), IL=1, iss=0x46 far=000000000000000000
Faulting task stack frame:
r22=0x414141414e4243ff r23=0x4141414000000000
r24=0x0000016118b14000 r25=000000000000000000
sp=0x00000000010b6cd0 lr=0x0000000001030454
pc=0x0000000001024bd4 psr=0x60000004
Channel 0xf9 SError, demonstrating a full register dump:
panic(cpu 1 caller 0xfffffe002c0d2540): PMP SERROR
Exception class=0x2f (SError interrupt), IL=1, iss=0
r00=0x0000000080010001 r01=0x000000000000000a
r16=0x0011110000000103 r20=0x000000000000000a
pc=0x000000000104aa58 psr=0x600002c5
The vulnerability is reachable by compiling and signing a binary with the com.apple.private.pmp.performance-spi entitlement, or by running as root.
Credit
Pan Zhenpeng of STAR Labs SG Pte. Ltd.
Timeline
- 2024-01-22 — Patch released: iOS/iPadOS 17.3, macOS Sonoma 14.3, macOS Ventura 13.6.4, macOS Monterey 12.7.3, tvOS 17.3
- 2024-04-24 — CVE-2024-27791 published by Apple