iPadOS, IOKit and Sandbox/MACF

I am trying to run a program that queries a device connected to the USB-C connection on my iPad Air (IpadOS 17). Some IOKit calls work and some fail, with the error message

Sandbox: iOSNXLauncher(5338) deny(1) iokit-get-properties iokit-class:IOUSBHostDevice property:sessionID

or something similar. Which entitlement should I use to be able to execute the IOKit calls needed to see, for example, the Device ID and the Vendor ID? I would like to use the IOKit calls to communicate withUSB devices.

If IOKit doesn't allow USB device communication in iOS, does DriverKit have all of the capabilities to query USB attached devices and pass data back and forth? I am trying to port a program from MacOS to iOS. The MacOS software uses "libUSB" to interface to USB devices. I am trying to use a version compiled for iOS but Sandbox is stopping me (even when Xcode has the "Sandbox App" option set to NO.).

Am I missing entitlements or will this approach not work?

Gene

On macOS, libUSB uses the methods in IOKit/usb/IOUSBLib.h. These are unavailable on iPadOS. DriverKit is available on iPadOS on devices with M1 or later processors. DriverKit doesn't have the same APIs as IOUSBLib, you would use it to make a Driver Extension (dext) which provides the functions you require.

You can read the device ID and the vendor ID without direct access to the device itself, by querying the IORegistry. In principle, you could communicate with a device using the user-space property accessors like IORegistryEntrySetCFPropert(y/ies) and IORegisteryEntryCreateCFPropert(y/ies), but in practice most drivers don't support the property setters, so you would have to write a driver extension which does. And if you go that far, you may as well support direct communication with the driver by implementing a user client and calling IOConnectCallMethod or its derivatives like IOConnectCallStructMethod.

I don't think you need special entitlements to read the IORegistry, but you do need them to communicate with drivers, and you driver needs specific entitlements which are tied to one or more specific USB vendor IDs. Reportedly, you can develop a driver without the entitlements, but I could never get that to work and have since been granted the entitlements so I never revisited the topic. See https://developer.apple.com/documentation/driverkit

@ssmith_c , I have a version of libUSB that I have compiled for iOS which uses the methods in IOKit in iPadOS. I can access some of the information from the device attached to the USB-C connector but not all of it. Sandbox denies some of the accesses but not all of them. If it could be made to work, then porting a software defined radio application , in theory, should be possible. If there is no way to make it work I would need a bridge between calls to libUSB and calls to DriverKit, and I know that would not be possible for me at the present based on what I don’t know. Gene

@W1EBR I know exactly what you mean (I'm trying to do something similar currently myself). Fortunately, my project is for our own hardware; we are entitled to our own USB vendor ID so we can make an iPadOS driver for our hardware.

If your SDR is your own, or that of a business partner, you/they can request the entitlement com.apple.developer.driverkit.transport.usb entitlement. If it were third-party hardware, but the software is open source, you can let users download and compile it to run locally. No entitlements are needed, but obviously the barriers to entry for most users is way too high. If the SDR is a commercial product, it is up to the vendor of the product to provide a driver.

There doesn't seem to be a way (yet? who knows?) to talk to arbitrary USB hardware on iPadOS. Apple would encourage you to file a feature request using Feedback Assistant if that's what you would like to able to do.

@ssmith_c Even IORegisteryEntryCreateCFProperty, in the attempt to read a device id, is denied by Sandbox.

@ssmith_c , I think, for the iPad, it isn't possible to compile it to run locally without entitlements. The DEXT loading mechanism needs a way to match the Vendor and Product IDs and the only way I know of to do that is to have them in the entitlements (on an iPad). Is this incorrect?

nine months too late, but here we are. For dext loading, the OS uses the IOKitPersonalities dictionary, which is in your driver's plist.

The entitlement is separate. For development, Xcode will make a special entitlement with idVendor="*", so you can play around with any device you like.

I don't think I've ever managed to use "sign to run locally" for a dext. Instead, I use development signing with our team ID.

I don't think I've ever managed to use "sign to run locally" for a dext.

Yeah, that’s not gonna work [1]. DriverKit is dependent on entitlements and those entitlements must be authorised by a provisioning profile. Sign to Run Locally results in an ad hoc signature, so there’s no stable signing identity to associate your code with its provisioning profile.

If you’re curious about how this all works, see the Inside Code Signing technote series.

Instead, I use development signing with our team ID.

And that is exactly what I recommend.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Well, you might be able to make it work by disabling SIP, but that’s not a good path forward.

iPadOS, IOKit and Sandbox/MACF
 
 
Q