kextd_personalities.c [plain text]
#include <IOKit/IOKitLib.h>
#include <IOKit/IOKitServer.h>
#include <IOKit/kext/OSKextPrivate.h>
#include <IOKit/IOCFSerialize.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <libc.h>
#include <zlib.h>
#include "kextd_main.h"
#include "kextd_personalities.h"
#include "kextd_usernotification.h"
#include "kextd_globals.h"
static OSReturn sendCachedPersonalitiesToKernel(Boolean resetFlag);
OSReturn sendSystemKextPersonalitiesToKernel(
CFArrayRef kexts,
Boolean resetFlag)
{
OSReturn result = kOSReturnSuccess; CFArrayRef personalities = NULL; CFMutableArrayRef authenticKexts = NULL; CFIndex count, i;
result = sendCachedPersonalitiesToKernel(resetFlag);
if (result == kOSReturnSuccess) {
goto finish;
}
if (!createCFMutableArray(&authenticKexts, &kCFTypeArrayCallBacks)) {
OSKextLogMemError();
goto finish;
}
recordNonsecureKexts(kexts);
count = CFArrayGetCount(kexts);
for (i = 0; i < count; i++) {
OSKextRef aKext = (OSKextRef)CFArrayGetValueAtIndex(kexts, i);
if (OSKextIsAuthentic(aKext)) {
CFArrayAppendValue(authenticKexts, aKext);
}
}
result = OSKextSendPersonalitiesOfKextsToKernel(authenticKexts,
resetFlag);
if (result != kOSReturnSuccess) {
goto finish;
}
personalities = OSKextCopyPersonalitiesOfKexts(authenticKexts);
_OSKextWriteCache(OSKextGetSystemExtensionsFolderURLs(),
CFSTR(kIOKitPersonalitiesKey), gKernelArchInfo,
_kOSKextCacheFormatIOXML, personalities);
finish:
if (result != kOSReturnSuccess) {
OSKextLog( NULL,
kOSKextLogErrorLevel | kOSKextLogIPCFlag,
"Error: Couldn't send kext personalities to the IOCatalogue.");
} else if (personalities) {
OSKextLog( NULL,
kOSKextLogProgressLevel | kOSKextLogIPCFlag |
kOSKextLogKextBookkeepingFlag,
"Sent %ld kext personalities to the IOCatalogue.",
CFArrayGetCount(personalities));
}
SAFE_RELEASE(personalities);
SAFE_RELEASE(authenticKexts);
return result;
}
static OSReturn sendCachedPersonalitiesToKernel(Boolean resetFlag)
{
OSReturn result = kOSReturnError;
CFDataRef cacheData = NULL;
if (!_OSKextReadCache(gRepositoryURLs, CFSTR(kIOKitPersonalitiesKey),
gKernelArchInfo, _kOSKextCacheFormatIOXML,
false, (CFPropertyListRef *)&cacheData)) {
goto finish;
}
OSKextLogCFString( NULL,
kOSKextLogProgressLevel | kOSKextLogIPCFlag |
kOSKextLogKextBookkeepingFlag,
CFSTR("%@"), CFSTR("Sending cached kext personalities to IOCatalogue."));
result = IOCatalogueSendData(kIOMasterPortDefault,
resetFlag ? kIOCatalogResetDrivers : kIOCatalogAddDrivers,
(char *)CFDataGetBytePtr(cacheData), (unsigned int)CFDataGetLength(cacheData));
if (result != kOSReturnSuccess) {
OSKextLog( NULL,
kOSKextLogErrorLevel | kOSKextLogIPCFlag,
"error: couldn't send personalities to the kernel.");
goto finish;
}
OSKextLogCFString( NULL,
kOSKextLogProgressLevel | kOSKextLogIPCFlag |
kOSKextLogKextBookkeepingFlag,
CFSTR("%@"), CFSTR("Sent cached kext personalities to the IOCatalogue."));
result = kOSReturnSuccess;
finish:
SAFE_RELEASE(cacheData);
return result;
}