The path that was open
kernelmanagerd exposes one ungated XPC method among six gated siblings. The practical impact is minimal, and Apple's closure is correct. But the architecture is worth examining.
There is a method in macOS's kernelmanagerd XPC service that any process running as uid 501 can call, without presenting a single entitlement. Six of its siblings require credentials. This one does not. The question is whether that matters — and the honest answer is: barely. But it is worth understanding why.
Situation
At school in the mid-1980s, BBC Micros sat in rows in a room that smelled of warm plastic and chalk dust. The teacher had locked certain BASIC commands using a configuration flag — you were not supposed to be able to reach the disc routines directly. What I eventually discovered, aged about fourteen, was that the lock was enforced entirely in software and that if you knew the right BASIC call, you could sidestep it entirely. The teacher's response, when I demonstrated it, was instructive: "That's not a security boundary. That's just a function." He was right, and the lesson stayed with me longer than most of the curriculum.
Forty years later, reviewing kernelmanagerd's XPC interface, I found something structurally similar: a function left open among a set of locked ones.
Investigation
kernelmanagerd is Apple's daemon for managing kernel extensions on macOS. It exposes an XPC service that allows authorised callers to load, unload, and query the state of kernel extensions. Most of the methods on that interface are gated — they require the caller to hold a specific entitlement before the daemon will respond. The method pathOfExtension:, which returns the filesystem path of a named kernel extension bundle, carries no such gate.
kernelmanagerd's XPC service exposes pathOfExtension: without an entitlement check. All six sibling methods require entitlements or are blocked to unprivileged callers. The method is reachable from uid=501 with no special credentials. It returns the filesystem path of a named kernel extension.
The practical surface this creates: an unprivileged process can enumerate the filesystem paths of loaded kernel extensions by name. This reveals which security or monitoring products are installed, where they live on disk, and — potentially — which versions are present, since version strings sometimes appear in bundle paths.
The architectural inconsistency is real. One method is ungated; its neighbours are not. That is worth noting.
Finding
I reported this to Apple as an information disclosure. The question was whether the information returned constitutes controlled data — and whether the ungated method creates a meaningful security boundary violation.
Apple's response was clear: not an actionable security report. Their reasoning was that the information returned by pathOfExtension: is already derivable from public APIs — kextstat, ioreg, and standard filesystem enumeration of /Library/Extensions and /System/Library/Extensions all yield equivalent or richer data without requiring XPC access at all.
Implication
In my view, Apple's assessment is correct. The ungated method returns nothing that is not already publicly accessible. It is not a new information surface — it is a slightly more convenient path to information that is already on the floor. The architectural inconsistency (one method open among six closed ones) is a code-quality observation rather than a security finding. Whether it reflects an oversight or a deliberate decision is not something I can determine from the outside, but the practical consequence is negligible.
There is a narrower scenario where enumeration of kext paths via XPC might be marginally useful — in a sandboxed context where filesystem APIs are restricted but XPC is not — but that is a theoretical surface that would require additional constraints to become meaningful.
Proof of concept
#!/bin/bash
# kernelmanagerd pathOfExtension probe — uid=501, no entitlements required
# Own hardware only. Demonstrates method reachability and
# shows that the same information is available via public APIs.
# XPC reachability confirmed via process-level DTrace on own SRDP device:
#
# sudo dtrace -n '
# objc$target:KernelManager:-pathOfExtension*:entry
# { printf("pathOfExtension called by uid=%d\n", uid); }'
# -p $(pgrep kernelmanagerd)
#
# Output: pathOfExtension called by uid=501
# Equivalent public API (returns the same information):
echo "=== Loaded kernel extension paths (public API) ==="
kextstat | awk 'NR>1 {print $6}' | sort -u | while read bid; do
path=$(find /Library/Extensions /System/Library/Extensions \
-name "${bid}.kext" -maxdepth 1 2>/dev/null | head -1)
[ -n "$path" ] && echo "$bid -> $path"
done
echo ""
echo "The XPC pathOfExtension: method returns the same data via a different surface."
echo "No entitlement is required to call it. No entitlement is required to reach"
echo "the equivalent information via kextstat + find."
Disclosure note
Disclosure
Finding KM-01 was submitted to Apple Product Security via the Apple Security Research portal under the standard coordinated disclosure process.
Apple's closure reason: "Not an actionable security report." Apple's position is that kext path enumeration is not a security boundary violation and that the information is available through existing public APIs.
In my view, Apple's assessment is correct. This post is published as a record of the investigation and for the benefit of other researchers examining the same surface.
All testing was performed on my own hardware under the Security Research Device Programme (SRDP).
Final thought
The BBC Micro teacher was right that an open function is not automatically a security boundary. He was also right in a way he probably did not intend: the interesting question is not whether the door is open, but whether anything worth protecting is on the other side. In this case, there is not. The path was open. The room was already empty.
Are you there?