macoskerneldiskkernel-extensionhfs+

Error when trying to create and mount a new HFS volume (in order to test filter scheme driver)


I am trying to test a IO kit sample app that implements a filter scheme. See section 10.7.10 here for context. As the source there is hard to cut and paste (and when I tried I got errors), I am using the source from here which builds.

In the last figure on that page (1038) it has a series of steps for creating and mounting a new HFS volume. The idea is to see that the KEXT is working and doing encryption. I have built the sample KEXT and tested with it, but I always get "No mountable file systems" error when I make the "open" call. I have verified the KEXT is properly loaded.

If I remove the "-partitionType" I am able to manipulate the volume normally (though this doesn't involve the KEXT).

Can someone please suggest what might be going wrong here?

Part of my confusion in figure 1038's script is the "detach" command that is run before the open. It fails for me, but I am not sure if that is what is causing the "open" after it to fail, or is unrelated.

$ sudo kextload /System/Library/Extensions/IOKitDriverTestApp.kext/
$ hdiutil create -size 32m -partitionType osxbook_HFS /tmp/crypto.dmg 
created: /tmp/crypto.dmg
$ hdiutil attach -nomount /tmp/crypto.dmg 
/dev/disk2              Apple_partition_scheme          
/dev/disk2s1            Apple_partition_map             
/dev/disk2s2            osxbook_HFS
$ diskutil list
/dev/disk0 (internal, physical):
[cut]
/dev/disk1 (synthesized):
[cut]
/dev/disk2 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     Apple_partition_scheme                        +33.6 MB    disk2
   1:        Apple_partition_map                         32.3 KB    disk2s1
   2:                osxbook_HFS                         33.5 MB    disk2s2
$ newfs_hfs -v Crypto /dev/rdisk2s2
Initialized /dev/rdisk2s2 as a 32 MB case-insensitive HFS Plus volume
$ hdiutil detach /dev/disk2
hdiutil: detach failed - No such file or directory
$ open /tmp/crypto.dmg
==> Get popup window with error "crypto.dmg" "No mountable file systems"

UPDATE: the question originally targeted the case when the KEXT was not loaded. Since I got that to work I changed it to reflect the case with the KEXT, which is more important anyway.

UPDATE2: It seems that eventually the kext is getting unloaded (possibly crashing). Sometimes it seems around the time of the "open", sometimes after. I tried adding statements like IOLog("CSD: init"), but none of them show up in the system log or console log. Looking for how else I can triage this (without needing a separate machine).

UPDATE3: Below is the output of when I try to start the KEXT. There are a bunch of warnings but since I have the signing check disabled I think it is still loading. Also I see it loaded via kextstat.

The other strange thing is I don't see any signs of this KEXT in the output of "ioreg", nor do I see any of the print statements from IOLog().

My-MacBook-Pro:Extensions myuser$ sudo kextutil -v /System/Library/Extensions/IOKitDriverTestApp.kext/
Defaulting to kernel file '/System/Library/Kernels/kernel'
Kext with invalid signatured (-67050) allowed: <OSKext 0x7fa53703ec70 [0x7fff8fe6faf0]> { URL = "file:///System/Library/Extensions/IOKitDriverTestApp.kext/", ID = "com.osxbook.driver.IOKitDriverTestApp" }
Code Signing Failure: code signature is invalid
Warnings: 
    Personality CFBundleIdentifier differs from containing kext's (not necessarily a mistake, but rarely done): 
        SimpleCryptoDisk
    Personality CFBundleIdentifier names a kext that can't be found: 
        'SimpleCryptoDisk' -> 'com.osxbook.driver.SimpleCryptoDisk'

Warnings: 
    Personality CFBundleIdentifier differs from containing kext's (not necessarily a mistake, but rarely done): 
        SimpleCryptoDisk
    Personality CFBundleIdentifier names a kext that can't be found: 
        'SimpleCryptoDisk' -> 'com.osxbook.driver.SimpleCryptoDisk'

/System/Library/Extensions/IOKitDriverTestApp.kext appears to be loadable (not including linkage for on-disk libraries).
Loading /System/Library/Extensions/IOKitDriverTestApp.kext.
/System/Library/Extensions/IOKitDriverTestApp.kext successfully loaded (or already loaded).
Invalid signature -67050 for kext <OSKext 0x7fa53703ec70 [0x7fff8fe6faf0]> { URL = "file:///System/Library/Extensions/IOKitDriverTestApp.kext/", ID = "com.osxbook.driver.IOKitDriverTestApp" }

UPDATE4: I adjusted the bundle ID in the plist so it matches, and now it is not giving the "names a kext that can't be found" error:

My-MacBook-Pro:Debug myuser$ sudo kextutil -v /System/Library/Extensions/IOKitDriverTestApp.kext/
Password:
Defaulting to kernel file '/System/Library/Kernels/kernel'
Kext with invalid signatured (-67050) allowed: <OSKext 0x7f8be663ecf0 [0x7fff866bcaf0]> { URL = "file:///System/Library/Extensions/IOKitDriverTestApp.kext/", ID = "com.osxbook.driver.IOKitDriverTestApp" }
Code Signing Failure: code signature is invalid
/System/Library/Extensions/IOKitDriverTestApp.kext appears to be loadable (not including linkage for on-disk libraries).
Loading /System/Library/Extensions/IOKitDriverTestApp.kext.
/System/Library/Extensions/IOKitDriverTestApp.kext successfully loaded (or already loaded).
Invalid signature -67050 for kext <OSKext 0x7f8be663ecf0 [0x7fff866bcaf0]> { URL = "file:///System/Library/Extensions/IOKitDriverTestApp.kext/", ID = "com.osxbook.driver.IOKitDriverTestApp" }

UPDATE5:

Now my OS consistently crashes every time I load the KEXT and then execute "hdiutil attach -nomount /tmp/crypto.dmg" (after creating /tmp/crypto.dmg).

It seems clear my KEXT is running now, but for some reason I still don't see the IOLog() statements anywhere. Will have to look through the system logs and see if there is any indication why it is crashing.

UPDATE6: I have been able to get a symbolicated kernel panic, but it is pointing to a different KEXT (which I don't think I have the source too). Below is the relevant part of it.

I tried using another version of the same test KEXT (here) without any changes (I have removed the IOLog() statements for now since they weren't showing up).

I see a note this was tested on Mac OS 10.6, but has anyone gotten this sample to work on 10.13.16 (High Sierra)?

...
0xffffff800c94f540 : 0xffffff800cb8776f mach_kernel : _kernel_trap + 0x70f
0xffffff800c94f6b0 : 0xffffff800ca1e1e0 mach_kernel : _return_from_trap + 0xe0
0xffffff800c94f6d0 : 0xffffff7f8d527251 com.apple.iokit.IOStorageFamily : __ZN9IOStorage8completeEP19IOStorageCompletioniy + 0x27
0xffffff81f7a4b980 : 0xffffff7f8d51a0c4 com.apple.iokit.IOStorageFamily : __ZN20IOBlockStorageDriver24prepareRequestCompletionEPvS0_iy + 0xc2
0xffffff81f7a4b9e0 : 0xffffff7f903afa7a com.apple.driver.DiskImages : __ZN13IOHDIXCommand8completeEiy + 0x26
0xffffff81f7a4ba00 : 0xffffff7f903adbfe com.apple.driver.DiskImages : __ZN22IOHDIXHDDriveOutKernel12processReplyEPK13HDIReplyOOL64P18IOMemoryDescriptor + 0x2be
0xffffff81f7a4ba60 : 0xffffff7f903aee9b com.apple.driver.DiskImages : __ZN32IOHDIXHDDriveOutKernelUserClient14processReply64EPK13HDIReplyOOL64 + 0xd3
0xffffff81f7a4bac0 : 0xffffff800d0c3959 mach_kernel : _shim_io_connect_method_structureI_structureO + 0x1c9
0xffffff81f7a4bb20 : 0xffffff800d0c1ae0 mach_kernel : __ZN12IOUserClient14externalMethodEjP25IOExternalMethodArgumentsP24IOExternalMethodDispatchP8OSObjectPv + 0x340
0xffffff81f7a4bb70 : 0xffffff800d0ca567 mach_kernel : _is_io_connect_method + 0x217
...

UPDATE7: I gave up on trying to use the SimpleCryptoDisk.cpp test app and started from scratch, adding a little bit of code at a time. I've had some success (the driver starts and I can see logging), though I don't really have anything working yet.

If I get stuck on this I may post another question, but I'll go ahead and mark pmdj's answer as correct since he answered my original question.

If anyone knows of a modified version of SimpleCryptoDisk that works on High Sierra I'd still like to know, however.


Solution

  • To answer your original questions:

    [Why "No mountable file systems" when not loading the kext and using partition type "osxbook_HFS"]

    As you can see, the Apple Partition Scheme uses arbitrary text strings for identifying partition type. macOS uses this string verbatim as the "content hint" which selects which file system type to attempt to automount on that volume. The HFS+ file system is only looking for Apple_HFS (and Apple_HFSX for case-sensitive)

    The idea behind the kext is that it itself matches the newly defined content hint and publishes a new storage nub object which in turn has the HFS+ content hint for the filesystem to pick up.

    Why hdiutil detach was failing

    $ hdiutil detach /dev/disk2
    hdiutil: detach failed - No such file or directory
    

    On current versions of macOS, you need to rewrite the command as either:

    $ hdiutil detach disk2
    
    or
    $ hdiutil detach /Volumes/VOLUMENAME
    

    I can't immediately answer your current question of why it's not working with the kext, but I can suggest you look at whether your kext is behaving as expected with regard to the IO Registry. Check with IORegistryExplorer or ioreg whether it's matching the volume with the special partition type, and whether it's creating and registering the virtual (decrypted) volume with the Apple_HFS content hint. Add the ioreg output (ioreg -w 0 -lirc YOUR_DRIVERS_CLASSNAME) to your question if unsure.