Files
vphone-cli/scripts/patchers/campo_mach_lookup_exceptions.py
zqxwceandClaude Opus 4.8 decda02ab4 cfw: jb/exp: Fix iOS 27 Campo crash-loop (sandbox mach-lookup exceptions)
iOS 27's Campo (wallpaper renderer) runs under the temporary-sandbox profile
(its own com.apple.private.sandbox.profile:embedded + no-container). On the 26.4
vphone600 kernel that builtin profile predates 27 and denies the backboard/
frontboard launch mach-services, so BKSDisplayServicesStart and then
+[BKSHIDEventDeliveryManager sharedInstance] fail their mach-lookups, log
"backboardd isn't running -- or we couldn't talk to it", and brk ~34ms after
launch -> continuous crash-loop, no wallpaper. JB-02d's container-upcall
force-success stops the exec-time autobox kill but does not grant these services.

Grant them through Campo's own com.apple.security.exception.mach-lookup.global-name
array (the sanctioned escape hatch, honored by temporary-sandbox -- Campo already
ships ~20 such exceptions; these launch services just aren't among them because
27's profile allows them directly). Applied at host-mount build time as step
JB-3b in cfw_install_jb.sh / cfw_install_exp.sh, re-signed with signcert.p12 via
ldid_sign_ent. The service list is merged by the external helper
scripts/patchers/campo_mach_lookup_exceptions.py (plistlib, not plutil -- the
entitlement key's dots would break plutil keypaths).

Hard-gated to 27.* on the mounted rootfs SystemVersion.plist (same gate as the
vpregister/DSC patches): skipped on 26.x/18.x, which don't need it and where
Campo.app also exists.

Verified on-device (17,3_27.0_24A5390f + cloudOS 26.4, JB): Campo launches and
stays up, no BKSDisplayServicesStart/BKSHIDEventDeliveryManager trap. Documented
as entry #14 in research/0_binary_patch_comparison.md.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_014McnrLRb5cZsTrpcBkvkj3
2026-07-23 16:50:41 +03:00

60 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Merge Campo's needed backboard/frontboard launch mach-services into an
entitlements plist's mach-lookup exception array, in place. See
0_binary_patch_comparison.md #14.
Usage: campo_mach_lookup_exceptions.py <entitlements.plist>
"""
import plistlib
import sys
EXCEPTION_KEY = "com.apple.security.exception.mach-lookup.global-name"
SERVICES = [
"com.apple.backboard.display.services",
"com.apple.iohideventsystem",
"com.apple.CARenderServer",
"com.apple.backboard.hid.services",
"com.apple.backboard.hid-services.xpc",
"com.apple.backboard.TouchDeliveryPolicyServer",
"com.apple.backboard.system-app-server",
"com.apple.backboard.watchdog",
"com.apple.backboard.oswatchdog",
"com.apple.backboard.altsysapp",
"com.apple.AttentionAwareness",
"PurpleSystemEventPort",
"PurpleWorkspacePort",
"com.apple.frontboard.systemappservices",
"com.apple.frontboard.workspace",
"com.apple.frontboardservices.systemappmanager",
"com.apple.frontboard.watchdog",
]
def merge(path):
with open(path, "rb") as f:
entitlements = plistlib.load(f)
existing = list(entitlements.get(EXCEPTION_KEY, []))
added = [s for s in SERVICES if s not in existing]
entitlements[EXCEPTION_KEY] = existing + added
with open(path, "wb") as f:
plistlib.dump(entitlements, f)
print(" [+] Campo mach-lookup exception count: %d (+%d added)"
% (len(entitlements[EXCEPTION_KEY]), len(added)))
def main(argv):
if len(argv) != 2:
print("usage: campo_mach_lookup_exceptions.py <entitlements.plist>",
file=sys.stderr)
return 2
merge(argv[1])
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))