Prefix research patch comparison doc and normalize root markdown names Rename research root markdown files to scoped topic names
5.9 KiB
launchd Boot Sequence Analysis (mount-phase-1 / data volume lookup)
Date: 2026-03-06
Target binary in IDA: launchd (Darwin Bootstrapper 7.0.0, libxpc_executables-3089.42.1~6)
Scope
This analysis focuses on the log segment:
mount-phase-1failed to lookup data volume - Attribute not foundmount: data volume missing, but not required in env: 1
and answers where launchd is involved vs where mount/APFS is actually failing.
Ground Truth from launchd (IDA)
1) Boot task source is embedded plist in launchd
- Embedded config plist string contains:
Bootdictionarymount-phase-1->Program=/sbin/mount,ProgramArguments=["mount","-P","1"]data-protection->Program=/usr/libexec/init_data_protection,CSIdentityOverride=com.apple.seputil
2) Boot task dictionary wiring
-
sub_10004D978:- reads launchd
__TEXT,__config - extracts
Bootdictionary - stores into
qword_10007F138
- reads launchd
-
sub_100047B94:- lookup task from
qword_10007F138 - runs gate check (
sub_100047C8C) - executes task by calling
sub_100047DD0
- lookup task from
3) Boot sequence order (relevant slice)
start->sub_1000489A4-> asyncsub_100048590sub_100048590task order includes:mount-phase-1data-protectionfinish-obliterationdetect-installed-rootsmount-phase-2
4) Task execution and failure handling
-
sub_100047DD0:- logs
Doing boot task posix_spawnp()actual executable- for non-async tasks waits via
sub_100049180
- logs
-
sub_100049180:- checks exit status
- if
RequireSuccess=trueand exit is failure -> callssub_100048D0C
-
sub_100048D0C:- logs
Boot task failed: %s - logs
Panicking in 3 seconds. - then panics
- logs
Key Conclusion: where the quoted error originates
failed to lookup data volume - Attribute not found is not generated by launchd internals.
In this path, launchd is only the orchestrator:
- launchd runs
/sbin/mount -P 1formount-phase-1 mountprintsfailed to lookup data volume...- launchd only sees child exit result, then decides whether to panic based on
RequireSuccess
So this error’s primary fault domain is in mount + APFS/IOKit interactions, not in launchd task scheduler code.
mount -P 1 call chain (IDA-verified)
Target binary: research/artifacts/launchd_23B85/mount.from_vm_disk.current
start@0x100003DC8- phase path calls
sub_100003480(&env)thensub_100003674()
- phase path calls
sub_100003480@0x100003480- reads
IODeviceTree:/filesystems/fstabpropertyos_env_type - calls
APFSContainerGetBootDevice(&CFString) - builds
/dev/<boot-container>string in global buffer
- reads
sub_100003674@0x100003674- calls
APFSVolumeRoleFind(<bootdev>, 0x40, &CFArray) - on non-zero return:
fprintf("%sfailed to lookup data volume - %s\n", ..., strerror(ret & 0x3fff))
- if single match, converts CFString -> data volume path
- calls
Important:
0x40is the queried role selector in this build.Attribute not foundcorresponds toENOATTR(93) afterret & 0x3fff.- phase-1 can continue with warning, but this often cascades into
data-protectionfailure in your failing trace set.
Updated Causality (with new control evidence)
User-provided control result:
cfw_install(without JB extras) reproduces the same failure.- TXM path is known-good in this setup.
Implication:
- JB-only userspace deltas are no longer primary suspects for this error.
- Current highest-confidence differentiator is kernel state/patch delta.
Plausible causes (re-ranked)
A. kernel-side causes (highest probability now)
- APFS role/device lookup path is denied/altered by kernel policy path for
mount(IOUC AppleAPFSUserClient ... MACFclass of failure). - Kernel APFS patch interaction causes role metadata read path to return "attribute not found".
- Kernel patch ordering or overlap in
fw_patch_jbmodifies behavior that minimal/non-JB flow does not.
B. mount userspace path causes (still relevant, but secondary to A)
mount -P 1phase logic expects Data role metadata that is unavailable under current kernel behavior.- Userspace APFS query path receives transformed errno/status from kernel and prints attribute-missing message.
C. launchd-level causes (currently de-prioritized)
- launchd task definition mismatch.
- spawn-level failures before mount logic.
- task gating differences.
These are less consistent with the new control result and with observed mount-origin log text.
Practical meaning
- For this failure, launchd reverse already gives enough certainty that launchd is orchestrator only.
- Next decisive work should move to APFS userspace API return-site tracing and corresponding kernel handlers.
- Detailed
mount -P 1failure/hang matrix is documented in:research/boot_mount_phase1_failure_matrix.md
Most likely kernel-side silent-fail line (current ranking)
APFSVolumeRoleFindpath reaches APFS userclient method and gets transformed deny/error (most consistent withIOUC AppleAPFSUserClient failed MACF ... mounthistory).- Base APFS entitlement bypass patch (
patch_apfs_get_dev_by_role_entitlement, patch #16) matched the wrong deny branch or altered control flow for role lookup. - Base sandbox-op stubs (mount/vnode related) hit an unintended target due ops-table drift.
Lower probability for this exact string:
- launchd plist/task ordering itself
- fstab format/ramdisk missing (would produce different dominant signatures)
Artifact notes
Current extracted launchd sample (for reproducible local reference):
research/artifacts/launchd_23B85/launchd.from_vm_disk.current- sha256:
411d730c95d99a088e94b673eff3fa73d6d3cc778b24b476cd0b7866cd037443
- sha256:
research/artifacts/launchd_23B85/launchd.plist.from_vm_disk.current- sha256:
dc972e30220b3e9e8323d23ce4a4737d849893dd79e305693de902ff65ddacab
- sha256:
Observed in this sample:
- no
/cores/launchdhook.dylibload command - launchd embedded boot task plist present and readable