How can I use the MAC policies from TrustedBSD inside an IOKit kernel extension?
I already have a working IOKit extension and I would like to add some policies to it.
For testing, I wrote two dummy extensions, one using IOKit and a generic one.
The generic extension is working flawlessly, whilst the IOKit one is generating a link error for the symbols mac_policy_register
and mac_policy_unregister
.
$ sudo kextutil -tn /tmp/MACPolicy.kext
kxld[com.Test.MACPolicy]: The following symbols are unresolved for this kext:
kxld[com.Test.MACPolicy]: mac_policy_register(mac_policy_conf*, unsigned int*, void*)
kxld[com.Test.MACPolicy]: mac_policy_unregister(unsigned int)
Link failed (error code 5).
Check library declarations for your kext with kextlibs(8).
$ sudo kextlibs -v 6 -undef-symbols /tmp/MACPolicy.kext
Kext user-space log filter changed from 0xff2 to 0xfff.
Kext kernel-space log filter changed from 0xff2 to 0xfff.
Kext library architecture set to x86_64.
Kext library architecture is x86_64 (unchanged).
For all architectures:
com.apple.kpi.iokit = 15.4
com.apple.kpi.libkern = 15.4
For x86_64:
2 symbols not found in any library kext:
__Z21mac_policy_unregisterj
__Z19mac_policy_registerP15mac_policy_confPjPv
I already added the specified libraries to my Info.plist
, as well as com.apple.kpi.dsep
, com.apple.kpi.unsupported
, com.apple.kpi.mach
or any combination of those, with no success.
All the information I could found about this was this thread on the darwin-kernel discussion list.
I am targeting OS X 10.11 for now.
Notice how the missing symbols are mangled as if they were C++ functions, but the functions in questions are actually plain C functions. This means when you're calling them from C++, they're using a declaration that's missing the extern "C"
linkage specifier. The MAC headers don't take into account C++, so when including them from a .cpp file, you need to wrap them in an extern "C"
block explicitly, like so:
extern "C" {
#include <security/mac_policy.h>
}
If your #include
is in a mixed C/C++ header file, you'll need to make it conditional on C++ compilation using #ifdef __cplusplus
as usual.