Files
cinder27/docs/KERNEL-RW-ASSESSMENT.md
T
JBJF c30aadf9bb kernel R/W assessment for the high/critical entries
- docs/KERNEL-RW-ASSESSMENT.md: per-primitive verdict. None of the six
  kernel-reachable bugs supplies both address and value control; the chain
  requirements (KASLR, grooming, reclaim, gadget, PAC/PPL) are listed per entry
- CVE-2026-113910.c: leak collector — 8 chunk configs x --loop, canonical
  pointer classification (kernel-text / kernel-data / kernel-other), --keep
  raw dump, --verbose; candidates are printed, never dereferenced
- 112705 / 65385 / 112696: explicit primitive-limit headers (DoS, fixed-offset
  write without leak, honest negative); no blind writes
- README: link the assessment and the new 113910 receipt (0 candidates, 16 runs)
2026-10-31 15:37:58 +08:00

7.5 KiB
Raw Blame History

Kernel read/write feasibility — high and critical dossiers

Scope: the kernel-reachable entries rated High or Critical in the Cinder27 dossiers. Question: can any of them be turned into arbitrary kernel read/write that does not panic the device?

Short answer: no, not from the material as it stands. One entry gives a real kernel heap leak (read), one gives a bounded read model, one gives a race receipt on a UAF-shaped bug. The write entries either write a constant at a fixed offset or never reach the kernel interface at all. This document records what each primitive actually provides, what an arbitrary-R/W chain still needs, and what was added to the POCs.

Guardrails

  • The host Mac was panicked once by the CVE-2026-112705 encode path. That path is never executed on the host again; its C twin refuses to submit a frame without --force-host.
  • No blind kernel writes are attempted from any POC. A wrong guess in the kernel heap is a panic, not a data point.
  • The simulator has no AppleAVE2 hardware encoder and no ANE kernel interface, so the write primitives cannot be exercised there either. Their app modules are split into a safe probe and a deliberate fire module.

Primitive inventory

CVE Entry Primitive as shipped Read Write Kernel R/W verdict
2026-112705 AppleAVE2 NumberOfTemporalLayers fixed-offset constant fill in the driver no fixed value, fixed offset DoS only. No address control, no value control. The original write-up says explicitly: no arbitrary read/write capability.
2026-65385 IOKit IOHIDEventAppendEvent fixed-offset write into a short heap allocation no bounded, offset fixed Not reachable as a primitive here. The POC stops at symbol resolution; the vendor-defined constructor is missing on the host. No leak, no reclaim, no gadget.
2026-112696 AppleH16ANEInterface kernel interface reachability no none observed No primitive. The ANE kernel symbols are absent for a third-party process; the module is an honest negative.
2026-112507 XNU ipc_port.c request-table race stale index → UAF-shaped race no none direct The only theoretical UAF path. The POC proves the interleaving survives; it does not produce a controlled free, a reclaim, or a leak.
2026-113910 decmpfs chunked zlib under-produced chunks expose uninitialised kernel heap through a file read yes (bounded) no Leak only. Useful as a KASLR step; cannot write.
2026-112554 GPT partition-name scan 72-B scan over a 28-B field yes (bounded, model) no Leak only. The C twin models the width; the real read runs in the storage kext.

What arbitrary kernel R/W actually requires

Every iOS kernel R/W chain needs five independent capabilities. A bug that supplies one of them is a chain step, not a chain.

  1. KASLR defeat — a kernel text or heap pointer with a known relationship to the unslid base. 113910 and 112554 can supply candidates; neither guarantees a text pointer, and a heap pointer alone does not give the slide.
  2. Heap grooming — deterministic placement of a victim object next to the corrupted allocation, in the same zone, at the same size class.
  3. Controlled reclaim / corruption — for a UAF: free the object, reallocate the slot with attacker-influenced contents, and keep a stale reference alive. For an OOB write: a value and an offset that land on a field worth corrupting.
  4. A read/write gadget — an object whose corrupted field yields a load or store of an attacker-chosen address (e.g. a length+pointer pair, a page-table entry, a thread's pcb pointer).
  5. PAC / PPL bypass — kernel code pointers are PAC-signed; page tables are protected by PPL on modern devices. A data-only path can sometimes avoid both, but it still needs 1–4.

None of the six entries supplies 2–5. 112507 is the only one that could plausibly reach step 3, and reaching it requires a device, kernel symbols, and a reclaim strategy that the repository does not have.

Per-entry notes

CVE-2026-112705 — fixed constant, fixed offset

The driver indexes a layer table with the declared count and writes a constant at a fixed offset past it. There is no attacker-chosen value and no attacker-chosen address. The only observable is a kernel data abort. Calling this "R/W" would require a second bug that turns the corrupted field into a pointer; nothing in the dossier provides one. The correct classification is a reliable kernel DoS.

CVE-2026-112507 — the UAF-shaped race

The ring allocates receive rights, arms two notification kinds per port, tears down half the ring, then sends to the survivors. The request-table index consumers are the target of the race. A weaponised version would need:

  • a win condition that is observable without panicking (a receipt, not a crash);
  • a same-zone reclaim object with controllable contents (Mach ports themselves are one candidate, but the request-table entry's layout is not attacker-shaped);
  • a stale consumer that dereferences the reclaimed slot after the free;
  • a leak to place the reclaim object and to find the kernel base.

The POC records -300 and invalid destination receipts and reports that the interleaving survived. That is the honest limit of a userspace race harness: it can show the window exists, not that the window is controllable.

CVE-2026-113910 — the leak that was worth improving

This is the only entry where more code produces more signal. The C twin now:

  • sweeps 8 chunk configurations (including produce=0, which promises 64 KiB per chunk and writes none of it);
  • repeats the sweep --loop N times;
  • classifies every 8-byte-aligned value as kernel-text (0xfffffff0…), kernel-data (0xffffffe0…), kernel-other, or user;
  • writes the raw readback to --keep out.bin for offline analysis;
  • never dereferences a candidate.

On the macOS host decmpfs does not engage for a file that already has data (the documented oracle), so the run reports zero candidates and 3.2 MB of plain 0x41 readback. On an iOS device where the chunked xattr is honoured, the same sweep is the KASLR step. It still does not write.

CVE-2026-112554 — a read-width model, not a kernel reader

The C twin builds the overlong-name GPT and walks the name field the way 27.0 does. It proves the scan width (72 B against a 28-B field) but the bytes come from the image, not from the kernel heap. Treat it as a seed/oracle model. The real read would have to run through the storage kext on a mounted image; that is not attempted on the host.

What was deliberately not done

  • No attempt to fire 112705 or 65385 on the host: both can panic the kernel, and a panic is not evidence of control.
  • No blind write into a guessed kernel address: with KASLR and PAC in play, a wrong guess is indistinguishable from a bug that does not work.
  • No claim that 112507 is exploitable: a race receipt is not a UAF primitive until the free/reclaim/stale-dereference sequence is observed.

Bottom line

Arbitrary kernel R/W without a panic is not achievable from these six entries as shipped. The maximum safe capability the lab now demonstrates is:

  • a repeatable kernel heap leak with pointer classification (113910);
  • a read-width model for the GPT scan (112554);
  • a race-window harness with receipts (112507);
  • honest negatives for the write entries that never reach a controllable primitive.

The next real step is not more code in this repository; it is a device session with kernel symbols, a reclaim strategy for 112507, and a stop condition for every write.