Abstract. CVE-2026-86876 is Apple’s CoreMedia out-of-bounds write: “a sandboxed process may be able to circumvent sandbox restrictions,” fixed “with improved bounds checking.”1 The candidate this note follows is CoreMedia’s metric event timeline, served to apps by mediaplaybackd. On iOS 26.6.2 (23G90) it has two independent bugs. FigMetricEventTimelineCreate allocates a prefix-sum table from the sum of client-supplied sizes and then writes it count times, a linear heap overflow whose qwords are fully chosen by the client. _met_addSubscriberForEventID turns a client EventID into a table index, checks only index < total with a signed compare, then loads subscribers[index] and, if that slot is NULL, stores a freshly created CFSet pointer there. iOS 26.7 (23H24) rejects non-positive counts and negative sizes, sizes the table from the count, and rejects negative and out-of-range indices. On a physical iPhone SE running 23G90, an ordinary development-signed app with no extra entitlements crashed mediaplaybackd three times at the out-of-range load, with fault addresses that match base + index × 8 exactly, and flipped the daemon’s subscriber state with a small negative index. On a research VM the same primitives produced a planted pointer in a sandbox-registration object, a use-after-free, and a type-confused CFSet call whose fault address was attacker bytes. Scope: protected files stayed EPERM in every run, no client-visible daemon address leak was found, and the type confusion did not reproduce on the physical phone. The bug class matches Apple’s text; the sandbox escape it describes was not reproduced.
1. Introduction
Apple credits Chris Bailey of Short Circuit.123 The 14 September pages list two other CoreMedia bugs next to this one: CVE-2026-64752 (crafted image, fixed by removing code, iOS 27 only) and CVE-2026-65344 (crafted video terminates an app, also an out-of-bounds write with bounds checking). The 23G90 → 23H24 CoreMedia diff therefore contains at least two out-of-bounds-write fixes, and the mapping in this note is a candidate until it is separated from CVE-2026-65344 (§10).
Layout: advisory (§2); binaries and the size diff (§3); the metric timeline service (§4); bug 1, the prefix table (§5); bug 2, the subscriber index (§6); physical iPhone results (§7); research VM results (§8); the sandbox question (§9); mapping caveats (§10); record and artifacts (§11).
Evidence labels used throughout.
- Apple-confirmed — advisory text and page membership.
- Patch-observed — ARM64 read on exact, hashed CoreMedia from both builds.
- Lab-observed (SE) — physical iPhone SE 2020, iOS 26.6.2 / 23G90, ordinary signed app, no debugger.
- Lab-observed (VM) — full-userspace 23G90 research VM, client run from a shell (unsandboxed), sometimes with Frida reading daemon memory. Never used as evidence of what a sandboxed app can do.
- Hypothesis — untested inference.
2. Where Apple lists it
| Advisory (14 Sep 2026) | CVE-2026-86876 |
|---|---|
| iOS 26.7 and iPadOS 26.7 | present, CoreMedia1 |
| iOS 27 and iPadOS 27 | present, CoreMedia2 |
| macOS Golden Gate 27 | present, CoreMedia3 |
| macOS Tahoe 26.7, Sequoia 15.8 | present |
| visionOS 27, watchOS 27 | present |
| tvOS 27 | absent |
| Item | Advisory text |
|---|---|
| Impact | A sandboxed process may be able to circumvent sandbox restrictions |
| Description | An out-of-bounds write issue was addressed with improved bounds checking |
CISA-ADP: CWE-787, CVSS 3.1 5.2 (AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N).
3. Binaries and what changed
| Side | Cache UUID | CoreMedia UUID | SHA-256 | Source ver. |
|---|---|---|---|---|
| iOS 26.6.2 / 23G90, iPhone17,3 IPSW | F216D3F4-7064-3359-8840-41C1D1A2A72E |
C83ABE72-6B63-3C92-805A-5D69F55BE6A3 |
e80ab627287660628664d30b006f600cee7e3f53510e297551cc69d9a0625e0e |
3330.13.2 |
| iOS 26.7 / 23H24, iPhone17,3 OTA | 5625EC35-B6D6-3C10-91B0-5B4C20FB77B7 |
B63D02BC-01BC-3F9A-8A83-90149364808B |
4792ba2af559a4a4d67602728a4f03cfbefa6f32bd29068d20be460a0582ab08 |
3330.13.101.5 |
23G90 is inside Apple’s “before 26.7” range; Apple does not name it. The physical SE’s crash reports name the same CoreMedia UUID as the IPSW extract, and the research VM’s loaded __text matches the extract byte for byte (SHA-256 2247c998…6925).
Of the functions present on both sides, 28 changed size. The ones that grew by 8 bytes or more:
| Symbol | 23G90 | 23H24 | Δ |
|---|---|---|---|
_met_publishEventDispatch |
0x334 |
0x3a8 |
+116 |
_hevcbridgeParseVDRRPUDataPayload |
0xb9c |
0xc08 |
+108 |
_met_subscribeByClassIDOnQueue |
0x11c |
0x164 |
+72 |
_met_addSubscriberForEventID |
0xd8 |
0x108 |
+48 |
_FigMetricEventTimelineCreate |
0x338 |
0x344 + cold stubs |
+12 |
_FigHEVCBridge_CreateDolbyRPUNAL |
0x2f98 |
0x2fa0 |
+8 |
Four of the six are the metric timeline. The two HEVC/Dolby Vision RPU functions are a separate parser fix (§10). Every FigSandbox* function, _HandleSandboxRegistrationMessage, and _checkRequestAgainstSandboxRules is the same size on both sides: whatever Apple fixed, it was not the sandbox-check code itself.
4. The metric event timeline service
mediaplaybackd serves com.apple.coremedia.mediaplaybackd.figmetriceventtimeline.xpc. Apps reach it through CoreMedia’s client half (FigMetricEventTimelineCreateRemote, …RegisterSubscriber, …Publish), which wraps FigXPC messages. metserver_replyingMessageHandler (0x197de5704) dispatches on a four-character opcode:
| Opcode | Meaning | Keys |
|---|---|---|
cret |
create a timeline | MaxNoOfClasses (count), EventCountByClassXPCArray (sizes) |
sevi |
subscribe by EventID |
ObjectID, EventID (int64) |
clsi |
subscribe a whole class | ObjectID, ClassID |
pubs |
publish an event | ObjectID, event |
disp |
dispose the timeline | ObjectID |
A timeline’s derived storage, as used by the code below:
| Offset | Field |
|---|---|
+0x10 |
total — sum of all class sizes, number of subscriber slots |
+0x18 |
count — number of classes (read only by the 23H24 code) |
+0x28 |
prefix — int64[count], prefix sums of the sizes |
+0x30 |
subscribers — CFSetRef[total] |
An EventID is class << 56 | low56. Its slot is prefix[class] + low56. Everything in that formula — the sizes that build prefix, the class, and low56 — comes from the client.
5. Bug 1: the prefix table is sized by the sum and filled by the count
5.1 Vulnerable side, 23G90
cret copies the client’s int64 array into a count × 8 buffer (that part is correct) and calls FigMetricEventTimelineCreate(alloc, count, sizes, …) at 0x197de586c. Inside (x21 = count, x23 = sizes):
; sum the sizes — no sign check, no overflow check
0x197dcf77c CMP X21, #1
0x197dcf780 B.LT zero_len
0x197dcf790 LDR X11, [X9], #8
0x197dcf794 ADD X8, X11, X8
0x197dcf798 SUBS X10, X10, #1
0x197dcf79c B.NE 0x197dcf790
0x197dcf7a0 LSL X25, X8, #3 ; request = sum * 8
0x197dcf7ac BL FigGetMallocZoneForMedia
0x197dcf7b0 MOV X3, #0x10040436913F5 ; malloc type id
0x197dcf7c0 MOV W1, #1
0x197dcf7c4 MOV X2, X25
0x197dcf7c8 BL malloc_type_zone_calloc
0x197dcf7cc STR X0, [X22,#0x28] ; prefix table
; fill it — count iterations, not sum
0x197dcf7f4 MOV X24, #0
0x197dcf7f8 LDR X8, [X22,#0x28]
0x197dcf7fc MOV X9, X21
0x197dcf800 STR X24, [X8], #8 ; write running sum, advance
0x197dcf804 LDR X10, [X23], #8
0x197dcf808 ADD X24, X10, X24
0x197dcf80c SUBS X9, X9, #1
0x197dcf810 B.NE 0x197dcf800
Whenever count > sum, the loop writes (count − sum) × 8 bytes past the allocation. The value written at step k is sizes[0] + … + sizes[k−1], so with negative sizes allowed every overflowing qword is an arbitrary int64 (choose sizes[k] = target[k+1] − target[k]).
Worked example from the first VM run: count = 0x1000, sizes = {1, 0, 0, …}. The sum is 1, the request is 8 bytes (16-byte slot), the loop writes 4096 qwords = 32768 bytes: 0 at offset 0, then 1 at offsets 8 through 32760. A debugger at the calloc return and loop end recorded x0 = 0x1020728d0, malloc_size = 16, final x8 = x0 + 0x8000, and the qword at +16 (a neighbor) changing from 0x15e8 to 1.
5.2 Fixed side, 23H24
0x197dfc738 CMP X21, #0
0x197dfc73c B.LE cold.8 ; count <= 0
0x197dfc740 CBZ X23, cold.7 ; no sizes array
0x197dfc784 LDR X9, [...], #8
0x197dfc788 TBNZ X9, #63, cold.6 ; any negative size
0x197dfc79c LSL X2, X21, #3 ; request = count * 8
...
0x197dfc7e4 STR X24, [X9, X8, LSL #3] ; loop bound is count
Table and loop now agree on count, and negative sizes are gone, so a client can no longer pick the overflowing values.
6. Bug 2: a signed subscriber index with only an upper bound
6.1 Vulnerable side, 23G90
sevi looks up the timeline by ObjectID and calls vtable +0x10, _met_subscribeByEventID, which runs _met_addSubscriberForEventID (0x197dd05b4) on the timeline’s queue. X21 is the client’s EventID; X20 is the storage from §4:
0x197dd05ec LDR X8, [X20,#0x28] ; prefix table
0x197dd05f0 ASR X9, X21, #0x38 ; class, signed, unchecked
0x197dd05f4 LDR X8, [X8,X9,LSL#3] ; prefix[class]
0x197dd05f8 AND X9, X21, #0xFFFFFFFFFFFFFF ; low56
0x197dd05fc ADD X21, X8, X9 ; index = prefix[class] + low56
0x197dd0600 LDR X8, [X20,#0x10] ; total
0x197dd0604 CMP X21, X8
0x197dd0608 B.GE error ; only index >= total is rejected
0x197dd060c MOV X19, X0
0x197dd0610 LDR X8, [X20,#0x30] ; subscribers
0x197dd0614 LDR X0, [X8,X21,LSL#3] ; read subscribers[index]
0x197dd0618 CBNZ X0, add ; already a set → just add
0x197dd061c BL FigGetAllocatorForMedia
0x197dd062c BL CFSetCreate
0x197dd0630 LDR X8, [X20,#0x30]
0x197dd0634 STR X0, [X8,X21,LSL#3] ; store new CFSet pointer
0x197dd0638 CBZ X0, fail
add:
0x197dd063c MOV X1, X19
0x197dd0640 BL CFSetAddValue ; slot contents treated as a CFSet
A client gets a negative index in one message: create a timeline with sizes {−N, N+2} (sum 2, so prefix[1] = −N) and subscribe to EventID = 1 << 56. The index is −N, which is < total. Three things follow:
- read:
subscribers[−N]is loaded from anywhere below the array; - write: if it is NULL, a new
CFSetpointer is stored there (value not chosen by the client, address chosen); - type confusion: if it is not NULL, whatever is there is passed to
CFSetAddValueas a set.
Because the address is subscribers + (index << 3) modulo 2^64, an index near −2^61 wraps to a positive offset while still passing the signed < total check, so the slot can be above the array as well. And because class is never bounded, prefix[class] is itself an out-of-bounds read for classes outside [0, count).
The other subscribe path, _met_subscribeByClassIDOnQueue (clsi), walks a range of slots starting at prefix[class] with the same unchecked arithmetic, i.e. the same read/plant/add for a range of slots. _met_publishEventDispatch computes the same index to read a slot and dispatch to the set’s members.
6.2 Fixed side, 23H24
0x197dfd5f0 TBNZ X21, #0x3F, error ; reject EventID with bit 63
0x197dfd5f4 LSR X8, X21, #0x38 ; class, now unsigned
0x197dfd5f8 LDR X9, [X20,#0x18] ; count
0x197dfd5fc CMP X8, X9
0x197dfd600 B.GE error ; class < count
0x197dfd604 LDR X9, [X20,#0x28]
0x197dfd608 LDR X8, [X9,X8,LSL#3]
0x197dfd60c AND X9, X21, #0xFFFFFFFFFFFFFF
0x197dfd610 ADDS X21, X8, X9
0x197dfd614 B.MI error ; negative index
0x197dfd618 LDR X8, [X20,#0x10]
0x197dfd61c CMP X21, X8
0x197dfd620 B.GE error ; index < total
0x197dfd62c LDR X0, [X8,X21,LSL#3]
That is the +48 bytes. _met_subscribeByClassIDOnQueue (+72) and _met_publishEventDispatch (+116) gain the matching checks.
7. Physical iPhone SE, sandboxed app
7.1 Setup
iPhone SE 2020 (iPhone12,8), iOS 26.6.2 / 23G90. The probe app is an ordinary development-signed app with no custom entitlements. It checks the loaded CoreMedia UUID, creates a timeline through FigMetricEventTimelineCreateRemote, registers a callback, then sends raw sevi/pubs messages on the same connection so it can control EventID exactly.
One mistake cost a day and is worth stating: the first builds wrote EventID with xpc_dictionary_set_uint64, and CoreMedia reads it with xpc_dictionary_get_int64. The type mismatch reads as 0, so every early “send=0, no crash” run never exercised the index at all. Every result below uses set_int64 and reads the value back before sending.
Reachability was confirmed against the daemon, not inferred from return codes:
| App input | App sees | mediaplaybackd logs |
ARM64 that produces it |
|---|---|---|---|
cret, count 0 |
-19450 |
err=-19450 at <>:182 |
0x197de57f4 → error 0xFFFFB406, line 0xB6 |
sevi, valid object, index ≥ total |
-19452 |
err=-19452 at <>:231 |
addSubscriber cold.1 |
sevi, ObjectID high bit flipped |
-16152 |
<< FigXPC >> err=-16152 at <>:6321 |
__figXPCServerLookupAndRetainAssociatedObject |
7.2 Three crashes at the out-of-range load
Input: sizes {−0x40000000, 0x40000002}, EventID = 0x0100000000000000, so index = −0x40000000 (−8 GiB). Three fresh app processes, three daemon deaths:
.ips |
Daemon PID | X8 (subscribers) |
X21 (index) |
X8 + X21×8 |
FAR |
|---|---|---|---|---|---|
…-005023.ips |
2802 | 0xd4b99c010 |
−0x40000000 |
0xb4b99c010 |
0xb4b99c010 |
…-005228.ips |
3063 | 0x795388010 |
−0x40000000 |
0x595388010 |
0x595388010 |
…-005241.ips |
3066 | 0x67d350010 |
−0x40000000 |
0x47d350010 |
0x47d350010 |
All three: EXC_BAD_ACCESS / SIGBUS / KERN_PROTECTION_FAILURE, CoreMedia UUID C83ABE72-…, runtime base 0x1a030b000 (slide 0x8630000), PC 0x1a0400614 = 0x197dd0614, the LDR in §6.1. Stack:
0 CoreMedia met_addSubscriberForEventID + 96
1 CoreMedia met_subscribeByEventIDOnQueue + 36
2 libdispatch _dispatch_client_callout + 16
3 libdispatch _dispatch_lane_barrier_sync_invoke_and_complete + 56
4 CoreMedia met_subscribeByEventID + 100
5 CoreMedia metserver_replyingMessageHandler + 788
6 CoreMedia figXPC_HandleMessage + 2024
7 libxpc _xpc_connection_call_event_handler + 112
The heap base moves with each restart; the instruction, index, and arithmetic do not. These faults are the read at 0x…614. The STR four instructions later never ran in these three.
7.3 A small negative index changes daemon state
With sizes {−3, 5} and the same class, the index is −3: a mapped slot 24 bytes below the array. The app publishes the event before and after sevi and counts callbacks:
neg-oracle: create=0 register=0 subscribe=0
prepub=0 precb=0 slot read as NULL → no subscribers → no callback
send1=0 sevi plants a CFSet at subscribers[-N]
publish=0 callbacks=1 publish finds the planted set → callback delivered
Same result in three new app processes and a fourth same-process repeat; a normal input’s direct publish gives the positive control of 1. Where the slot held malloc metadata instead of NULL (index −1), the daemon accepted the sevi and then died in the next publish (objc_msgSend ← met_publishEventDispatch, KERN_INVALID_ADDRESS at 0x0040000000000010), twice. So from inside the sandbox the app has a three-way probe of any slot near the array: NULL (silent), a set it planted (callback), or garbage (daemon crash).
7.4 The prefix overflow from the app
cret with sizes {−1000000, 1000002, −102, 102} and count 4 (sum 2, two qwords of overflow) returned 0 on the phone in some runs and -16155 in others. After a successful one, sevi on every timeline, including a control created afterward, returned -19452, while new cret still worked. That is consistent with the overflow corrupting neighboring prefix tables (§8.3), but on the phone there was no way to read them, so it stays an observation, not a mechanism.
clsi from the app returned -16155; from the VM shell it returned 0. The same code also shows up on the VM in states that have nothing to do with policy, so whether clsi is gated for sandboxed clients is unresolved.
8. Research VM: what the primitives can do with addresses known
The VM is iPhone17,3 / 23G90 with full userspace. The client is a CLI started over SSH, not sandboxed. Where addresses appear, Frida read them from the daemon; the client had no way to learn them.
8.1 A planted pointer in a sandbox-registration object
cre8 creates a sandbox registration: FigSandboxRegistrationCreate stores the retained ExtensionPath at +0x10, calls sandbox_extension_consume on the token bytes, and stores the handle at +0x20. With the registration at 0x69d2c0540 and the subscriber array at 0x69d420000, EventID = 0x010000fffffd40aa aimed the STR at registration+0x10. Before: 0. After: 0x69d434090, the new CFSet. The registration and the array live in different zones (DefaultMallocZone vs. CMMediaZone) 10.6 MB apart; the signed index crosses that. The offset between them was −431472 and −417148 slots in two later daemon instances, so it is not a constant an attacker could hard-code.
8.2 Use-after-free into type confusion, no addresses needed
Subscriber arrays of two timelines created back to back sit two slots apart in their type pool. That gives a constant index without any leak:
T1 sizes {1,1} victim, T1.subscribers = X
T2 sizes {-2,4} attacker, T2.subscribers = X + 16, prefix[1] = -2
1. sevi on T2, class 1, low56 0 → index -2: CFSet into T1.subscribers[0]
2. publish → callback 1 (plant confirmed)
3. disp T1 → finalizer CFReleases each slot: set freed
4. 200 × cre8 → DefaultMallocZone spray, chosen path bytes
5. sevi on T2 again → CFSetAddValue on the freed, reclaimed slot
The daemon died in __CF_IS_OBJC ← CFSetSetValue ← met_addSubscriberForEventID with KERN_INVALID_ADDRESS at 0x656c7070415e6e6f and “possible pointer authentication failure.” Read little-endian, those bytes are on^Apple: part of the path string sprayed in step 4. The daemon dereferenced attacker bytes as an object’s isa.
The same sequence from the sandboxed app on the physical SE planted (callback 1), disposed, sprayed, and ran the second sevi without a crash: post_cb=1, i.e. the freed slot had not been reclaimed by the spray. The likely reason is that production xzone malloc keeps type-segregated pools, so a CFData/CFString allocation does not land on a freed CFSet; that is an inference from the outcome, not a measured layout.
8.3 Prefix overflow onto a neighboring timeline
Prefix tables of small timelines are 16-byte neighbors in their own pool, and freed slots are reused LIFO. With Frida reading the tables:
create T_B {1,1}, T_C {1,1} T_C.prefix = {0, 1}
disp T_B T_B's 16-byte slot freed
create T_E {-1000000, 1000002, -102, 102}, count 4, sum 2
T_E reuses T_B's slot; qwords 2-3 overflow
T_C.prefix = {2, -100}
After that, sevi and publish on T_C use an index the attacker wrote. This removes the need for negative sizes on the victim and is the reason the 23H24 create-side checks matter.
8.4 Limits found on the VM
- No overflow into pointers from bug 1. The sizes copy buffer, the prefix table, the timeline object, and the subscriber array are four different typed allocations in four different regions. A linear prefix overflow stays among prefix tables (integers).
- Client-side self-kill.
FigMetricEventTimelineCreateRemotebuilds a local mirror timeline with the same buggy loop, so acount > sumcreate through the framework overflows the client’s heap first (PAC_EXCEPTIONinmfm_alloc). Attacks have to send rawcret. - No leak in the replies. Full dumps of
sevi/pubs/clsi/staereplies contain only.ErrorReturnand.Token(the daemon PID).ObjectIDs are(pid << 48) | (server_number << 40) | counter | typewith no heap bits.CFCopyDescriptionof a timeline prints%p, but only a debugger called it. - Value not chosen. The write in bug 2 stores a
CFSetpointer; it cannot write an arbitrary value.
9. The sandbox question
Apple’s impact sentence is about circumventing the sandbox. Every authorization oracle tried on the physical SE stayed closed:
openof/private/var/mobile/Mediaand/usr/libexec/mediaplaybackd:EPERMbefore and after the negative-index state change, in the same process; the kernel kept loggingfile-read-datadenies.FigShared_CopyDiskCacheParamson a protected directory: returns 0 to the app, but the kernel denied the app’sfile-issue-extensionand the daemon’sfile-write-createofdiskcacherepository.plistboth before and after. A 0 from that API is not an authorization signal; the client path continues after-17507.sandbox_checkqueries agreed: no path tested was “app denied, daemon allowed” for writing.
What is established is the step before an escape: a sandboxed app can make a privileged daemon read and write out of bounds, and on a research VM the write can corrupt a sandbox-registration object and the resulting use-after-free gives attacker bytes as an object pointer. What is missing is a client-visible leak to aim the write on a real device, a reclaim that works under production malloc, and any protected resource actually becoming accessible.
10. Mapping caveats
- The same update fixes CVE-2026-65344 (crafted video, out-of-bounds write). The HEVC/Dolby Vision RPU parser changes (
_hevcbridgeParseVDRRPUDataPayload+108 adds a pre-write upper bound) match that video wording; the metric changes match the sandbox wording. That split is a reading of the advisory, not something Apple published. - The metric fixes cover every path that computes the index (create,
sevi,clsi, publish), which is what a deliberate fix for this bug class looks like. It does not prove Apple’s report used the same route. - 23H24 has not been run with the same app. The fixed-side behavior in §5.2/§6.2 is from ARM64 only.
11. Record and artifacts
| Item | Result | Label |
|---|---|---|
| Bug 1 | prefix table sum×8, filled count times; client-chosen qwords |
Patch-observed |
| Bug 2 | signed index, upper bound only; OOB read, conditional pointer write, type confusion | Patch-observed |
| Fix | count/size checks, count×8 table; bit 63, class, ADDS/B.MI, upper bound |
Patch-observed |
| Sandboxed app → daemon | three SIGBUS at 0x197dd0614, FAR = base + index×8 |
Lab-observed (SE) |
| Sandboxed app state change | callbacks 0 → 1 after negative-index sevi |
Lab-observed (SE) |
| Pointer planted in registration | +0x10: 0 → CFSet, debugger-supplied addresses |
Lab-observed (VM) |
| UAF → type confusion | fault at 0x656c7070415e6e6f (on^Apple) |
Lab-observed (VM); not on SE |
| Protected access, leak, code execution, 23H24 replay | not shown | — |
| Artifact | SHA-256 |
|---|---|
mediaplaybackd-2026-09-29-005023.ips |
44f7634c6557e3fb9d31fa9bde6ad7c6fc79586201ac7f49a03f54fce3b31d3f |
mediaplaybackd-2026-09-29-005228.ips |
bb4ce48b3d59a2524a9b6f7b14f47c661a5a8d5b6838aa18aa9fee76ddadc34f |
mediaplaybackd-2026-09-29-005241.ips |
f356955e1a7a86b72d1103b6c3f5e132f044bbc89f7f8bd69e46d163ea1a53fc |
| Normalized crash fingerprint (all three) | 707b713a6a9924d09854365f55a3f7eaafe0b1c8ac314649fdc6b8c7bc330981 |
| Probe app executable (far-negative build) | eb28a38e3bee2ab6a8a1de563498afc013843dfc715e43bd5b6013d847eb5939 |
| Probe app executable (count-0 control) | 54f9b6146a642f92116e40f13859d8d0c3917861aaa8ea40c1a786de4c7f2fbb |
| 23G90 CoreMedia | e80ab627287660628664d30b006f600cee7e3f53510e297551cc69d9a0625e0e |
| 23H24 CoreMedia | 4792ba2af559a4a4d67602728a4f03cfbefa6f32bd29068d20be460a0582ab08 |
[1] Apple, “About the security content of iOS 26.7 and iPadOS 26.7,” 14 September 2026. https://support.apple.com/en-us/149041
[2] Apple, “About the security content of iOS 27 and iPadOS 27,” 14 September 2026. https://support.apple.com/en-us/149034
[3] Apple, “About the security content of macOS Golden Gate 27,” 14 September 2026. The same CoreMedia entry is on the Tahoe 26.7, Sequoia 15.8, visionOS 27, and watchOS 27 pages. https://support.apple.com/en-us/149035