commit 20e97b315a4973ea847052d2b81c25d4aa805210
parent 4754d7c8b9283a3e9dc250f22caaf1ec0f0aa59e
Author: umhau <umhau@example.invalid>
Date: Wed, 21 Oct 2026 12:00:05 +0000
HPM RE: user-client gate is root OR entitlement; unattended recovery design notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat:
1 file changed, 28 insertions(+), 0 deletions(-)
diff --git a/tools/kernel/HPM_RE.md b/tools/kernel/HPM_RE.md
@@ -325,3 +325,31 @@ Stuck state (adapter partner status HPD=0 since [time redacted], induced by HID
`iecsCommand(route 0, 'DRST' = 0x44525354, flags 0)` on RID 1 (Port-USB-C@2):
returned 0 in 50 ms at 140.855422; CMD1 = 0, DATA1 byte0 = 0; display ADD 4320x2160@60 at
143.064422 (+2.209 s). No physical replug. Repeatability trials in progress (vr0).
+
+## 9. User-client access gate is OR, not AND (vr1, static, VERIFIED in disassembly)
+`AppleHPMUserClient::initWithTask` @ 0xfffffe0009b49570:
+- super::initWithTask; on failure -> false.
+- w21 = IOUserClient::clientHasPrivilege(token, "root") (0 = caller is root)
+- ent = copyClientEntitlement(task, "com.apple.USBCEntitlement"); w22 = (ent == kOSBooleanTrue)
+- allow if (w21 == 0) || w22 (branches 0x9b49614 / 0x9b4961c / 0x9b49620 / 0x9b49624)
+- deny: logs two strings (0x747f6d5, 0x747f733), returns false -> plugin creation fails (seen as 0xe00002be).
+=> An unprivileged (non-root user) process ad-hoc signed with com.apple.USBCEntitlement=true is admitted (AMFI is off,
+ so the entitlement is honoured). No sudo needed. Matches hardware: unsigned non-root user failed; signed non-root user read OK.
+Per-selector: handlers seen (0, 2, 3) only validate argument counts; no extra privilege check observed on the
+selector-2 path. Not every handler audited.
+
+## 10. Unattended recovery: integration review (vr1, design, no hardware)
+- Privilege: either sign the app itself with com.apple.USBCEntitlement, or (narrower) a small signed helper the
+ app execs. No root, no sudo cache. Both rely on AMFI staying off (amfi_get_out_of_my_way=1).
+- Target selection, once per attempt, never polled: AppleHPMDevice with RID == 1 whose child is
+ `Port-USB-C@2` (PortNumber 2), and open the plug-in on its AppleHPMARMI2C parent. Refuse RID 0 (hub, headset
+ USB, Mac power). Optional: confirm reg 0x03 == "APP " and reg 0x58 byte0 bit1 (DP alt mode active) before DRST.
+- Command: iecsCommand(route 0, 0x44525354 'DRST', flags 0). Driver itself polls CMD1 for ~100 ms.
+ Check: return 0 -> then read DATA1 (reg 0x09) byte0 == 0. 0xe00002c6 = firmware !CMD; 0xe00002d6 = timeout.
+- Bound it: whole helper run <= ~1 s; app waits for CGDisplay ADD of vendor 8718 with a timeout (e.g. 5 s;
+ observed +2.2 s), then re-captures. Rate-limit (e.g. max 3 DRST per minute, exponential backoff) and log
+ every attempt with epoch timestamps + return codes.
+- Trigger: headset display REMOVE (track the captured CGDirectDisplayID, not vendor of a removed id) and no
+ ADD within a short grace window. Self-heals were ADD within ~0.7-0.8 s, so a ~1 s grace avoids DRST
+ racing a self-heal; tune with trial data. HID 0x05 panel-off is a secondary signal only.
+- Never read IOPortTransportStateDisplayPort properties in a loop; one-off reads only, or none.