Introduction

talk about what this series of posts is gonna be about mention background at mercadolibre

What is a System Extension ?

A System Extension is an application that lets you extend the capabilities of the operating system from user space. This is done by utilizing 3 different frameworks. In this post we are only going to talk about the first two.

System Extension Types

One system extension can use make use of both the Endpoint Security and the Network Extension frameworks at the same time. We will see how that works later on.

System extensions can come in the form of an application bundle but if they are only an Endpoint Security extension they can also come as a Launch Daemon.

In the case of an app bundle we will have the main application binary myapp that will be responsible for loading and unloading the extension that will be located in Library/SystemExtensions as a separate bundle.

System Extension Folder Structure

How does a System Extension start ?

In order for macOS to load our extension we need to send an activation request from our client like this:

import SystemExtensions

let extensionBundleID = "com.company.myapp.Agent"
let delegate = ExtensionRequestDelegate()
// We can also send a deactivationRequest
let request = OSSystemExtensionRequest.activationRequest(forExtensionWithIdentifier: extensionBundleID, queue: .main)
request.delegate = delegate
OSSystemExtensionManager.shared.submitRequest(request)

It is important the identifier we supply to the request be identical to the one we set in the CFBundleIdentifier key of the extension’s Info.plist file.

We also need to define a delegate that will receive the response from the system to our request in one of four methods:

import SystemExtensions

class ExtensionRequestDelegate: NSObject, OSSystemExtensionRequestDelegate {

    // This is called when the request was successfull
    func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) {
    }

    // This is called when the request failed for some reason.
    func request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) {
    }

    // This is called in case the extension is pending approval from the user.
    func requestNeedsUserApproval(_ request: OSSystemExtensionRequest) {
    }

    // This is called in case we load an extension when there is one already running.
    // We can compare both the existing and new extension version numbers and decide what we want to do.
    func request(_ request: OSSystemExtensionRequest,
                 actionForReplacingExtension existing: OSSystemExtensionProperties,
                 withExtension extension: OSSystemExtensionProperties) -> OSSystemExtensionRequest.ReplacementAction {
        return .replace // or .cancel
    }
}

Once the extension loads for the first time the system will prompt the user with a pop up like this:

System Extension Pop Up

If we were deploying our extension through an MDM we could create a Profile to automatically allow our extension and avoid the popup.

We can list and manage our system extension with the systemextensionsctl tool. In order to remove system extensions with this tool we have to disable SIP.

$ systemextensionsctl --help
systemextensionsctl: usage:
	systemextensionsctl developer [on|off]
	systemextensionsctl list [category]
	systemextensionsctl reset  - reset all System Extensions state
	systemextensionsctl uninstall <teamID> <bundleID>; teamID can also be '-' (for matching empty Team ID)
	systemextensionsctl gc  - garbage collect orphaned system extension(s)

$ systemextensionsctl list
2 extension(s)
--- com.apple.system_extension.endpoint_security (Go to 'System Settings > General > Login Items & Extensions > Endpoint Security Extensions' to modify these system extension(s))
enabled	active	teamID	bundleID (version)	name	[state]
*	*	ABCDEFGH00	com.company.myapp.Agent (2.0.0/1)	Agent	[activated enabled]
*	*	ABCDEFGH00	com.company.myapp.Agent (1.0.0/1)	Agent	[terminated waiting to uninstall on reboot]

How is a System Extension built ?

Endpoint Security Framework

Network Extension Framework