3
kernel: DK: MyDriver-0x100000f45: provider entitlements check failed
kernel: DK: IOUserServer(com.MyDriver-0x100000f45)::exit(Entitlements check failed)
kernel: (com.MyDriver.dext) Kernel requested exit (Entitlements check failed)

I'm trying to create a driver using PCIDriverKit. Cannot find any reasonable sample code for this.

My problem is that I'm trying to access all devices, and even though I've put their masks correctly in the Info.plist (0x12345678&0x000000000) and the com.apple.developer.driverkit = TRUE and com.apple.developer.driverkit.transport.pci entitlements.

For most of the device I get the above errors in the macOS log. In A KEXT I was using before the same mask worked perfectly fine.

SIP is disabled of course, and system extension developer mode is on.

I'm using the "Sign to run locally" option in XCode at the moment as this is a development phase.

How can I get a DEXT to open all PCI devices on my Mac?

Edit: These are the entitlements of the DEXT according to codesign -d --entitlements -:

▒▒qq<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>com.apple.developer.driverkit</key>
        <true/>
        <key>com.apple.developer.driverkit.transport.pci</key>
        <array>
                <dict>
                        <key>IOPCIPrimaryMatch</key>
                        <string>0x12345678&amp;0x00000000</string>
                </dict>
        </array>
        <key>com.apple.security.app-sandbox</key>
        <true/>
        <key>com.apple.security.get-task-allow</key>
        <true/>
</dict>
</plist>

amfid logs:

amfid: [com.apple.MobileFileIntegrity:amfid] Basic requirement validation failed, error: (null)
amfid: /Library/SystemExtensions/{SOME_GUID}/com.MyDriver.dext/com.MyDriver signature not valid: -67050
pmdj
  • 22,018
  • 3
  • 52
  • 103
jreing
  • 281
  • 1
  • 11
  • What's the *value* of your PCI transport entitlement? Have you ensured this is correct? (Also, note that Apple is unlikely to grant you a wildcard entitlement, so you may want to work with DTS to figure out what they *will* grant you before investing lots of development effort.) – pmdj Jul 04 '21 at 11:56
  • The value of the PCI transport entitlement is an array containing a dictionary that contains a IOPCIMatch string 0x12345678&0x000000000 ( like required by Apple). This worked with a KEXT before... – jreing Jul 04 '21 at 12:13
  • Kexts don't use entitlements, so it's hardly surprising that loading your kext didn't fail with an entitlements error. Have you checked the entitlements have been correctly embedded in the built binary? Use `codesign -d --entitlements` on the dext. Does `amfid` log anything when you attempt to load your dext? I'm not sure if "Sign to run locally" works at all with dexts, so failing all else, you may wish to sign with a development certificate. – pmdj Jul 04 '21 at 12:20
  • 1
    Thanks for your response, I've edited the post to add the output from your suggestions. Does Apple mention anywhere that the Sign to run locally doesn't work with DEXTs? Because if don't use PCIDriverKit (just use IOUserResource "virtual" device without a PCI transport entitlement) then I am able to load the DEXT and print Hello world etc, even with "Sign to run locally". – jreing Jul 04 '21 at 13:06
  • 1
    The `amfid` log certainly looks like it might be causing you trouble, so [I recommend trying with `amfi_get_out_of_my_way=1`](https://stackoverflow.com/a/63486231/48660). Unfortunately, I so far haven't had time to systematically go through and exactly work out what the minimum requirements are for loading various kinds of dexts without being given the full set of entitlements by Apple. In your test without PCIDriverKit, did you have the basic `com.apple.developer.driverkit` entitlement set? If not, disabling AMFI should almost certainly help. – pmdj Jul 05 '21 at 09:27
  • I've not exactly worked out what disabling SIP by itself achieves in terms of code signing, but my hypothesis is that it removes the basic DriverKit entitlements check. However, the various DriverKit families' entitlements checks are definitely NOT disabled (you can see this in the IOPCIFamily source code) so you do have to set the entitlement in your dext binary. And I think as soon as you do that, AMFI gets involved and shuts you down. I should probably do that detailed analysis one of these days… – pmdj Jul 05 '21 at 09:41
  • 1
    Having said all that, I assume you've noticed that [DriverKit's view of the `IOService` API](https://developer.apple.com/documentation/driverkit/ioservice) does not include a `Probe()` method, so matching all PCI devices in the system will prevent their normal drivers from being loaded. (except for built-in devices, and except during early boot IOKit matching) – pmdj Jul 05 '21 at 09:45
  • Yes I've noticed that trying to match all devices (With "sign to run locally") blocks my keyboard, mouse and screen. Didn't know the exact reason for that - so thanks for pointing out a link to explain this. Is there anyway to work around this? Does Apple have a "blacklist" option I can add to the Info.plist or something like that (to prevent my driver from accessing certain devices, but still try to look for all)? – jreing Jul 06 '21 at 07:05
  • I did disable amfid now. Now still getting: kernel: DK: MyDriver-0x100000430: provider entitlements check failed kernel: DK: IOUserServer(com.MyDriver-0x100000430)::exit(Entitlements check failed) but at least the AMFID errors did go away. Any other ideas what to look for? – jreing Jul 11 '21 at 08:52
  • What's the `IOServiceDEXTEntitlements` property value for the `IOPCIDevice` you're trying to match? Either there's something unexpected there, or the entitlements simply aren't "sticking" for your binary for some reason. Note that for prototyping/testing purposes you can also set the `kIODKDisableEntitlementChecking` flag by adding `dk=0x8001` to your `boot-args` kernel command line. (0x8000 is the aforementioned flag, 1 needs to be there or DriverKit ends up completely disabled.) – pmdj Jul 11 '21 at 09:16
  • "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.pci")) . The entitlement file for my DEXT also has com.apple.developer.driverkit.transport.pci as an entitlement of course. Should I add IOServiceDEXTEntitlements as a key somewhere? Will try the boot arg. Are all these boot args documented somewhere? – jreing Jul 11 '21 at 10:34
  • 1
    *Should I add IOServiceDEXTEntitlements as a key somewhere?* No, that's for creating further restrictions on clients of your object and won't help in this case. – pmdj Jul 11 '21 at 14:58
  • 1
    *Are all these boot args documented somewhere?* Nowhere officially, and nowhere centrally, no. I know about this one by reading the kernel source. – pmdj Jul 11 '21 at 14:58
  • I still have the sneaking suspicion that "Sign to run locally" might be what's making things worse than if you were using a normal "Apple Developer" cert, but I'm not 100% sure. – pmdj Jul 11 '21 at 14:59
  • Thank you very much. With the dk=0x8001 I've finally succeeded in opening a device... This has been a very helpful thread. Are you referring to the source code here https://opensource.apple.com/release/macos-1101.html ? – jreing Jul 11 '21 at 15:46
  • Yes, that's where you can get the source code from. The main kernel source is in the 'xnu' package, PCI specific stuff is in 'IOPCIFamily'. I'll add an answer to this question that summarises the workarounds, although as you can see I don't have a definite, authoritative explanation of what exactly is going wrong. – pmdj Jul 11 '21 at 19:09
  • I noticed I didn't answer your PCI device blacklist question, which is tangential to your actual problem. I don't think there's an explicit blacklist, but (aside from the fact that I'm not quite clear on why you'd want to match *all* devices) you could use more than one matching personality, and instead of a total vendor wildcard, you could for example use a series of clever bit masks to only match devices with a vendor ID that doesn't match either Apple or Intel devices, for example. There is also the concept of a `built-in` device, which actually requires additional entitlements to match. – pmdj Jul 11 '21 at 19:29
  • If you want to ask more questions about PCI matching, I suggest you post a new question though, we've already covered a large amount of ground in this one. – pmdj Jul 11 '21 at 19:30

1 Answers1

4

I don't have a 100% answer as to why it's going wrong in your case. To load a dext on an unmodified system, you definitely need the following when codesigning your dext:

  • Sign with a 'Developer ID Application' certificate identity and be notarised, or signed with an 'Apple Developer' certificate
  • Embedded code signing entitlements including the generic DriverKit entitlement, any family-specific entitlements, and entitlements regarding user client access if necessary.
  • A provisioning profile from Apple which matches:
    1. The code signing entitlements you are embedding in the dext.
    2. The type and specific instance of the code signing identity you are using to sign the dext.
    3. The Application & Bundle ID of the dext.
    4. If using an Apple Developer signing identity, the hardware IDs of the Macs on which you will be testing the dext.

For local testing, you can try the following things to temporarily work around code signing issues:

  • Disabling System Integrity Protection (SIP). For purposes of DriverKit extensions, this disables some codesigning checks.
  • Disabling DriverKit-specific entitlements checks. This turns off checking for a lot of family-specific entitlements. To disable the checks, set flag 0x8000 in the dk kernel boot argument, which is a bitfield. Note that unless you set flag 0x1, DriverKit will be entirely disabled. So use dk=0x8001 to disable DriverKit entitlement checks.
  • Disabling AMFI checks. AMFI will normally kill your process if you try to claim entitlements which need to be enabled in a provisioning profile. You can disable AMFI with the amfi_get_out_of_my_way=1 kernel boot argument.

Obviously, you only have limited control over the provisioning profile, as the entitlements in it must be approved by Apple. (For this reason, if you're planning to ship your dext publicly, I generally recommend you try to work out what entitlements you might need before starting full development on the dext, and request them from Apple. The process can take months.) So while it would be interesting to know the exact minimum combination of workarounds required when you don't have these profiles, I haven't exhaustively tested this out yet. I realise this doesn't help much with getting your dext as close to shipping as possible while still waiting for Apple to grant missing entitlements. Hopefully one of these days I can systematically explore and document all of this.

pmdj
  • 22,018
  • 3
  • 52
  • 103