syspolicy.m   [plain text]

/*
* syspolicy.m
* kext_tools
*
* Copyright 2017 Apple Inc. All rights reserved.
*
*/
#import <Foundation/Foundation.h>

#import <SystemPolicy/SystemPolicy.h>
#import <bootstrap.h>
#import "syspolicy.h"
#import "kext_tools_util.h"

// Basic global state - perform initialization once and rely on that for future calls
static BOOL gInitialized = NO;
static SPKernelExtensionPolicy *gSystemPolicy = nil;

static BOOL
isSystemPolicyLinked() {
return NSClassFromString(@"SPKernelExtensionPolicy") ? YES : NO;
}

static BOOL
isSystemPolicyServiceAvailable() {
BOOL serviceIsAvailable = NO;
mach_port_t syspolicy_port = MACH_PORT_NULL;
kern_return_t kern_result = 0;
kern_result = bootstrap_look_up(bootstrap_port,
"com.apple.security.syspolicy.kext",
&syspolicy_port);
serviceIsAvailable = (kern_result == 0 && syspolicy_port != 0);
mach_port_deallocate(mach_task_self(), syspolicy_port);
return serviceIsAvailable;
}

static void
initializeGlobalState() {
BOOL useSystemPolicy = isSystemPolicyLinked() && isSystemPolicyServiceAvailable();
if (useSystemPolicy) {
gSystemPolicy = [[SPKernelExtensionPolicy alloc] init];
}
gInitialized = YES;
}

Boolean
SPAllowKextLoad(OSKextRef kext) {
Boolean allowed = true;

if (!gInitialized) {
initializeGlobalState();
}

if (gSystemPolicy) {
NSString *kextPath = (__bridge_transfer NSString*)copyKextPath(kext);
allowed = [gSystemPolicy canLoadKernelExtension:kextPath error:nil] ? true : false;
}

return allowed;
}

Boolean
SPAllowKextLoadCache(OSKextRef kext) {
Boolean allowed = true;

if (!gInitialized) {
initializeGlobalState();
}

if (gSystemPolicy) {
NSString *kextPath = (__bridge_transfer NSString*)copyKextPath(kext);
allowed = [gSystemPolicy canLoadKernelExtensionInCache:kextPath error:nil] ? true : false;
}

return allowed;
}