Hi all,
I'm building an iOS app extension using ExtensionKit that works exclusively with its containing host app, presenting UI via EXHostViewController.
I'd like the extension to have read-only access to the host's task for process introspection purposes. I'm aware this would almost certainly require a special entitlement.
I know get-task-allow and the debugger entitlement exist, but those aren't shippable to the App Store. I'm looking for something that could realistically be distributed to end users.
My questions:
- Does an entitlement exist (or is one planned) that would grant an extension limited, read-only access to its host's task—given the extension is already tightly coupled to the host?
- If not, is this something Apple would consider adding? The use case is an extension that needs to inspect host process state without the ability to modify it.
- Is there a path to request such an entitlement through the provisioning profile process, or is this fundamentally off the table for App Store distribution?
It seems like a reasonable trust boundary given the extension already lives inside the host's app bundle, but I understand the security implications. Any insight appreciated.
Thanks!
Thanks for the extra context. At this point I feel comfortable talking about technical stuff…
Oh wait, there’s one more business-y thing. My focus is on technical stuff. I don’t work for App Review and can’t make definitive statements about their policies.
OK, now let’s talk technical…
Mach is a capability-based system [1]. For you to get access to a Mach port, someone who already has access must share their access with you. So, who has access? And how can you convince them to share?
In this case only two entities have access:
- The ‘system’
- The target process itself
There’s no way to convince the system to share its access, at least on iOS [2]. So the only option is to get the target process to give you access to itself.
In theory, this should be trivial:
- Your app calls
mach_task_selfto get a send right for its control port. - It then sends your extension a copy of that right via XPC.
In practice, there are complications.
IMPORTANT I’ve never tried this sort of thing on iOS, so I’ve no idea whether it’ll work at all. And if it does, I’m concerned about its long-term binary compatibility. I’ll come back to that point below.
Task control port send rights are a serious security concern, and thus Apple is invested in limiting their use. My primary experience with this is an macOS, where the system supports variants of this port that have more limited uses. You can see evidence for this in various places:
- In
<mach/task_special_ports.h>there’s a variety of special ports that represent the task port with limitations, for example,TASK_INSPECT_PORT. - Conforming to Mach IPC security restrictions discusses task identity tokens, as a way for the system to pass an exception handler the identity of a task without passing it a task control port.
These limitations have rolled out steadily over the years, and it wouldn’t surprise me if that process continued into the future. My experience is that, on macOS, we go the extra mile to provide some sort of ‘escape hatch’ so that existing programs can continue working. That’s less common on iOS, where we just don’t expect iOS apps to be monkeying around with Mach IPC.
Note The documentation for the com.apple.security.hardened-process.platform-restrictions entitlement contains this chestnut: “instruct the system to protect against particular attacks that target … Mach messaging.” At some point someone will ask me what that actually means. Fortunately that hasn’t happened yet (-:
And all of this is in addition to my general warning about Mach APIs. Mach APIs are supported, but they’re tightly bound to the kernel and thus tend to have more compatibility problems than higher-level APIs. I’ve been warning folks about this for decades. I think this example is instructive. It’s not specific to the Mach IPC subsystem, but that’s kinda the point: All of Mach is like this.
So, you should feel free to take this idea for a spin. If it works in development, use TestFlight to confirm that it works for apps targeting the App Store. If so, you then have to think carefully about whether you want to continue down this path given the potential compatibility pitfalls.
I’d love to know how far you get, so please do update this thread as you go.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] In this sense of that phase.
[2] On macOS you have options, like getting a list of tasks from the host or everyone’s favourite [3] task_for_pid. Neither is an option on iOS.
[3] Well, not everyone’s favourite. I think it’s safe to assume that the Apple engineers who are responsible for platform security are not fans (-: