Skip to content

fix(imagemounter): derive EPRO/ESEC from RestoreRequestRules for TSS#781

Open
aluedeke wants to merge 2 commits into
mainfrom
fix/ddi-mount-tss-restore-request-rules
Open

fix(imagemounter): derive EPRO/ESEC from RestoreRequestRules for TSS#781
aluedeke wants to merge 2 commits into
mainfrom
fix/ddi-mount-tss-restore-request-rules

Conversation

@aluedeke

@aluedeke aluedeke commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Problem

Personalized developer-disk-image (DDI) mounts fail on fresh iOS devices with Apple TSS status 94 — "This device isn't eligible for the requested build." Xcode, ideviceimagemounter (libimobiledevice) and pymobiledevice3 all mount the same DDI on the same device without issue.

Root cause

Modern DDI BuildManifest.plist components (LoadableTrustCache, PersonalizedDMG) no longer carry literal EPRO/ESEC values. Those flags are expressed through the LoadableTrustCache component's RestoreRequestRules, evaluated against the device's personalization parameters (production mode, security mode, img4 support).

getSignature read the (absent) literals as Go's zero value and sent EPRO=false, ESEC=false. For a production device Apple TSS rejects that with status 94.

The bug was masked by the on-device personalization manifest cache: MountImage first tries QueryPersonalizationManifest and, on a hit, skips TSS entirely. Any device that had been personalized before (e.g. via Xcode) mounts fine; the failure only surfaces on a freshly-provisioned device that must personalize through TSS.

Fix

  • personalized_image.go: parse RestoreRequestRules; make EPRO/ESEC *bool so absent is distinguishable from false; add applyRestoreRequestRules + restoreRuleConditionsMet, mirroring Apple's libauthinstall / pymobiledevice3 rule evaluation.
  • tss.go: keep any literal EPRO/ESEC, then apply the manifest's rules for this device (ApProductionMode/ApSecurityMode/ApSupportsImg4 = true) before sending the request. Also include the TSS response message in the error so future failures are diagnosable.
  • restore_request_rules_test.go: device-free unit tests (production+secure → EPRO/ESEC true; development → false; unmatched/unknown conditions; 255 sentinel).

Verification

Reproduced status 94 on an iPhone SE (iPhone12,8, iOS 26.5.2) via a fresh TSS request; with the fix the fresh TSS request succeeds and the image mounts, for both an older and the latest (Xcode 26.6, 17F113) DDI. go build ./..., go vet ./ios/imagemounter/, gofmt, and the new unit tests all pass.

🤖 Generated with Claude Code

aluedeke and others added 2 commits July 2, 2026 15:19
Previously returned cleanly (exit 0) on mount error, silently bypassing
set -e in launch.sh and letting the pod continue with no testmanagerd.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Personalized DDI mounts failed on fresh devices with Apple TSS status 94
("This device isn't eligible for the requested build.").

Modern developer-disk-image build manifests no longer carry literal EPRO/ESEC
values on their components (LoadableTrustCache, PersonalizedDMG). Those flags are
expressed via the LoadableTrustCache component's RestoreRequestRules, evaluated
against the device's personalization parameters (production mode, security mode,
img4 support). We read the absent literals as Go's zero value and sent
EPRO=false, ESEC=false, which TSS rejects for a production device.

The failure was masked on devices that already had an on-device personalization
manifest cached (QueryPersonalizationManifest), since those skip TSS entirely. It
only surfaced on freshly-provisioned devices that must personalize via TSS.

Fix:
- Parse RestoreRequestRules and make EPRO/ESEC pointers so absent is
  distinguishable from false.
- Apply the rules to each trusted manifest entry using the device's parameters,
  mirroring Apple's libauthinstall / pymobiledevice3.
- Surface the TSS response message in the error to make future failures
  diagnosable.

Adds device-free unit tests for the rule evaluation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aluedeke aluedeke force-pushed the fix/ddi-mount-tss-restore-request-rules branch from 04ffed5 to d6fdcbe Compare July 2, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant