I am trying to build a custom kernel extension for macOS catalina 10.15.7 and XCode 12.4 to access a third-party USB-Wifi dongle (Alfa Network AWUS036NHA with Atheros AR9271 chipset). Since the manufacturer does not officially support macOS Catalina 10.15 and later versions, the Wifi dongle must be accessed via custom USB drivers.
I found a promising repository that claims support for this chipset: https://github.com/T1T4N/Atheros-AR9271. Building the kernel extension succeeds, however, loading fails.
Anyway, you can pretty much ignore the background since I think this is a general problem in custom kernel development for latest macOS versions.
There are two ways of loading a kext from an untrusted source. First by completely or partially disabling SIP via
# in recovery mode:
$ csrutil disable
$ csrutil enable --without kext
or second, by adding the TEAMID to the trusted sources
$ codesign --display --verbose <name-of-kext>
# do this in recovery mode:
$ /usr/sbin/spctl kext-consent add <TEAMID>
I went with the first option and disabled SIP completely for now. I am fully aware of the consequences of disabling SIP and will later enable SIP again.
The driver, which I want to compile, relies on the following function call to the StandardUSB.h
library. This header is part of the IOKit
kext.
CleanAtheros.cpp
...
funcDesc = (const FunctionalDescriptorHeader *) StandardUSB::getNextDescriptorWithType(fInterface->getConfigurationDescriptor(), (const Descriptor *) funcDesc, CS_INTERFACE);
...
I successfully compiled the code and tried to load the kext with the following commands:
$ sudo chmod -R 755 CleanAtheros.kext
$ sudo chown -R root:wheel CleanAtheros.kext
$ sudo kextutil -v CleanAtheros.kext
This gave me the output:
> Defaulting to kernel file '/System/Library/Kernels/kernel'
> Notice: /Users/kesenheimer/tools/Atheros-AR9271/CleanAtheros.kext has debug properties set.
> Kext with invalid signature (-67050) allowed: <OSKext 0x7ff510d2f1b0 [0x7fff85288ce0]> { URL = "file:///Users/kesenheimer/tools/Atheros-AR9271/CleanAtheros.kext/", ID = "com.gubawang.AR9271.CleanAtheros" }
> Code Signing Failure: code signature is invalid
> /Users/kesenheimer/tools/Atheros-AR9271/CleanAtheros.kext appears to be loadable (not including linkage for on-disk libraries).
> Loading /Users/kesenheimer/tools/Atheros-AR9271/CleanAtheros.kext.
> Disabling KextAudit: SIP is off
> KextAudit initialized: audit=F
> (kernel) Notice - new kext com.apple.driver.usb.AppleUSBHostPlatformProperties, v1.2 matches prelinked kext but can't determine if executables are the same (no UUIDs).
> (kernel) kxld[com.gubawang.AR9271.CleanAtheros]: The following symbols are unresolved for this kext:
> (kernel) kxld[com.gubawang.AR9271.CleanAtheros]: __ZN11StandardUSB25getNextDescriptorWithTypeEPKNS_23ConfigurationDescriptorEPKNS_10DescriptorEh
> (kernel) kxld[com.gubawang.AR9271.CleanAtheros]: __ZN15IOUSBHostDevice9metaClassE
> (kernel) Can't load kext com.gubawang.AR9271.CleanAtheros - link failed.
> (kernel) Failed to load executable for kext com.gubawang.AR9271.CleanAtheros.
> (kernel) Kext com.gubawang.AR9271.CleanAtheros failed to load (0xdc008016).
> (kernel) Failed to load kext com.gubawang.AR9271.CleanAtheros (error 0xdc008016).
> Failed to load /Users/kesenheimer/tools/Atheros-AR9271/CleanAtheros.kext - (libkern/kext) link error.
> Failed to load /Users/kesenheimer/tools/Atheros-AR9271/CleanAtheros.kext - (libkern/kext) link error.
> Check library declarations for your kext with kextlibs(8).
Note the two error messages:
> (kernel) kxld[com.gubawang.AR9271.CleanAtheros]: The following symbols are unresolved for this kext:
> (kernel) kxld[com.gubawang.AR9271.CleanAtheros]: __ZN11StandardUSB25getNextDescriptorWithTypeEPKNS_23ConfigurationDescriptorEPKNS_10DescriptorEh
> (kernel) kxld[com.gubawang.AR9271.CleanAtheros]: __ZN15IOUSBHostDevice9metaClassE
When I search for the missing symbols, I get the kext module where these symbols are defined:
$ kextfind -dsym "__ZN11StandardUSB25getNextDescriptorWithTypeEPKNS_23ConfigurationDescriptorEPKNS_10DescriptorEh"
> /System/Library/Extensions/IOUSBHostFamily.kext
$ kextfind -dsym "__ZN15IOUSBHostDevice9metaClassE"
> /System/Library/Extensions/IOUSBHostFamily.kext
which seems to be fine. I have verified that this kext is loaded:
$ kextstat | grep "com.apple.iokit.IOUSBHostFamily"
> 27 20 0xffffff7f8112e000 0xfa000 0xfa000 com.apple.iokit.IOUSBHostFamily (1.2) 14D49A36-567A-3AA7-9449-EA6615643E1A <26 25 24 8 7 6 5 3 1>
Additionally, as suggested by the output above, I checked with kextlibs which kernel extensions are needed by the kext:
$ kextlibs CleanAtheros.kext
> For x86_64:
> com.apple.iokit.IOUSBHostFamily = 1.2
> com.apple.kpi.iokit = 19.6
> com.apple.kpi.libkern = 19.6
> For arm64e:
> No libraries found.
>
> 297 symbols not found in any library kext.
I can not figure out how to resolve the missing symbols. These are my questions:
- Am I missing something obvious?
- Is it necessary to have the kext signed, even though SIP is disabled?
- If so, can I sign a kext without an apple developer account for personal use? I tried signing it, however, no matter what I do the error is
code signature is invalid
. - I tried to add
IOUSBHost.framework
to the project, since the missing symbols are defined in this framework as well. However, the symbols can still not be found, and attempts to sign the kext fail.
Additionally, here are my attempts changing the build settings:
Hope, anyone has a better insight than me in this case...