System Extensions

RSS for tag

Install and manage user space code that extends the capabilities of macOS using System Extensions.

System Extensions Documentation

Posts under System Extensions tag

106 Posts
Sort by:
Post not yet marked as solved
1 Replies
674 Views
Today, I applied the latest security patch to my Mac Studio, and on reboot, I had no networking. It appears to have been a system extension issue. At one point, I needed to "Allow" Apple system software in System Settings. I found that strange. I thought I'd document the issue and my resolution in case someone else runs into this. (1) I did the usual - reboot, shutdown & restart, reboot my Eero mesh; changed from Wi-Fi to wired Ethernet. Nothing worked. (2) I do have my own application that uses a network system extension, so I went through the system extension uninstall process (using the API). Still no joy. I then tried to reinstall the network extensions, but that didn't seem to work. I was never prompted to open the System Settings app. I think the network system extension had not actually been removed. I deleted the app (which should remove the network system extension). Still no joy. Interestingly, launchctl still showed a crashed network system extension (no PID, status -9) (3) I then disabled SIP, rebooted, and used systemextensionsctl to remove the network system extension. While doing this, I discovered an old network system extension from several years ago tied to one of my old organizations and may have been built for Intel CPU. I deleted that too. (If I had to guess, it might have been that old network system extension that caused the problem.) Reenabled SIP Rebooted. (4) At some point I got an interesting alert from Apple about System Extension errors. And when I opened System Settings, I had to allow an extension from Apple?! (5) Networking is now working. I reinstalled my application from TestFlight, installed the network system extension, and everything is still working. (6) Summary I lost networking after applying the security update. Worried that it might be my program, I tried uninstalling the network system extension, but I could not cleanly uninstall and reinstall my network system extension as I've done many times before. I found an old network system extension; deleted both network system extensions with SIP disabled. I had to Allow Apple software. Everything works (including my app with its network system extension installed). I am not sure what the root cause was. My old network system extension? The fact I needed to Allow Apple software? My current app and its network system extension?
Posted
by
Post marked as solved
2 Replies
399 Views
Hey folks, I have an application that ships a CoreMedia I/O system extension to create a virtual camera. We separately ship an "uninstaller" app, which is a notarised AppKit app. This uninstaller removes the app, containers, and the system extension via the following API: let request = OSSystemExtensionRequest.deactivationRequest(forExtensionWithIdentifier: pluginIdentifier, queue: .main) request.delegate = self OSSystemExtensionManager.shared.submitRequest(request) The OSSystemExtensionRequest API does correctly deliver metadata via propertiesRequest(forExtensionWithIdentifier: …), but when we attempt to remove the extension using the above snippet, we get a failure OSSystemExtensionError.extensionNotFound. The uninstaller app is signed with the same entitlements and certificate as the host app. It also embeds a copy of the system extension as required by the API. I think the crux of the issue is: Should this be expected to work? We're all code-signed correctly etc, and the only difference is that the removal request is coming from an app with a different bundle identifier to the one that installed it start with. Thanks!
Posted
by
Post not yet marked as solved
1 Replies
279 Views
Can we return NEPacketTunnelProvider's NEPacket to macOS kernel? Snippet- packetFlow.readPacketObjects {[weak self] packets in As per network rules, packets read from packetFlow. After parsing packets, in some conditional use cases(such as ip), if we decide not to handle the packets, could we return it to kernel? We can easily achieve it in NETransparentProxyProvider by returning false from below method. We are looking for similar mechanisms to do return the traffic to Kernel. override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool May we achieve the same with any other Network.framework or low level API? If any advance Code-level support could solve this issue, we could raise a TSI as well.
Posted
by
Post not yet marked as solved
3 Replies
431 Views
I have implemented an AppProxyProvider (NETransparentProxyProvider) and I am able to capture traffic with it. I am also able to define network rules allowing me to exclude some traffic: let settings = NETransparentProxyNetworkSettings(tunnelRemoteAddress: "127.0.0.1:8080") settings.includedNetworkRules = [ NENetworkRule(remoteNetwork: NWHostEndpoint(hostname: "0.0.0.0", port: "0", remotePrefix: 0, localNetwork: nil, localPrefix: 0, protocol: .TCP, direction: .outbound) ] Now the documentation states that if I want to capture localhost traffic, I need to explicitly add the following rule: NENetworkRule(remoteNetwork: NWHostEndpoint(hostname: "127.0.0.0", port: "0", remotePrefix: 8, localNetwork: nil, localPrefix: 0, protocol: .TCP, direction: .outbound) and if I want to capture ipv6 localhost address: NENetworkRule(remoteNetwork: NWHostEndpoint(hostname: "::1", port: "0", remotePrefix: 128, localNetwork: nil, localPrefix: 0, protocol: .TCP, direction: .outbound) All this works great. Now I am having trouble capturing external ipv6 traffic. For example my ISP supports ipv6 and facebook.com resolves to 2a03:2880:f128:181:face:b00c:0:25de on my machine. I am unable to write any rule allowing me to capture with the system extension such traffic. Either I get errors that the network mask cannot be greater than 32 or the traffic simply doesn't flow through the extension. Here's an example request that I would like to capture: curl https://facebook.com -kvp * Trying [2a03:2880:f128:181:face:b00c:0:25de]:443... * Connected to facebook.com (2a03:2880:f128:181:face:b00c:0:25de) port 443 (#0) * ALPN: offers h2,http/1.1 * (304) (OUT), TLS handshake, Client hello (1): * (304) (IN), TLS handshake, Server hello (2): * (304) (IN), TLS handshake, Unknown (8): * (304) (IN), TLS handshake, Certificate (11): * (304) (IN), TLS handshake, CERT verify (15): * (304) (IN), TLS handshake, Finished (20): * (304) (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 * ALPN: server accepted h2 * Server certificate: * subject: C=US; ST=California; L=Menlo Park; O=Meta Platforms, Inc.; CN=*.facebook.com * start date: Aug 26 00:00:00 2023 GMT * expire date: Nov 24 23:59:59 2023 GMT * issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert SHA2 High Assurance Server CA * SSL certificate verify ok. * using HTTP/2 * h2 [:method: GET] * h2 [:scheme: https] * h2 [:authority: facebook.com] * h2 [:path: /] * h2 [user-agent: curl/8.1.2] * h2 [accept: */*] * Using Stream ID: 1 (easy handle 0x7fcb5c011e00) > GET / HTTP/2 > Host: facebook.com > User-Agent: curl/8.1.2 > Accept: */* > < HTTP/2 301 < location: https://www.facebook.com/ < strict-transport-security: max-age=15552000; preload < content-type: text/html; charset="utf-8" < x-fb-debug: uWVEw8FZUIXozHae5VgKvIDY5lgH/4Aph+h+nJNJpIr7jFZIFGy9LRLGCSwPudcFBdi4Mf4rLaKsNGCBxHDmrA== < content-length: 0 < date: Fri, 17 Nov 2023 14:14:03 GMT < alt-svc: h3=":443"; ma=86400 < * Connection #0 to host facebook.com left intact Can this be achieved?
Posted
by
Post not yet marked as solved
0 Replies
315 Views
Currently I am using below network rule to read all traffic. But I want to skip to read particular port on localhost. What is NetworkRule to exclude reading from particular port on localhost? let networkRule = NENetworkRule(remoteNetwork: nil, remotePrefix: 0, localNetwork: nil, localPrefix: 0, protocol: .any, direction: .any)
Posted
by
Post marked as solved
1 Replies
472 Views
I have a macOS app that installs an endpoint system extension. After the user clicks "Allow" to allow it to be installed, the user must still scroll up to the "Full Disk Access" section and enable full disk access for the system extension. It is easy for the user to forget to do this. Is there an API (or other easy way) for the installing app to check whether the endpoint system extension has been granted full disk access? I would like to display some big message in the GUI saying "You must enable Full Disk Access" until they do.
Posted
by
Post not yet marked as solved
1 Replies
300 Views
I want to understand in which API triggers this below popup. 1. This below code always trigger popup after fresh install which make sense: `//manager NETunnelProviderManager manager.connection.startVPNTunnel(options: [:])` 2. This below code sometime triggers popup intermittently. Ideally this shouldn't trigger or always trigger. I tried running this code in loop to check this behaviour, some time around 50th or sometime around 88th execution observed this popup. config.providerBundleIdentifier =“bundleId” config.serverAddress = "Connection managed by app”Name// let manager = NETunnelProviderManager() manager.protocolConfiguration = config manager.localizedDescription = “xyz” manager.saveToPreferences(completionHandler: { (saveError) -> Void in }``` no where startVPNTunnel called in 2nd code sample.
Posted
by
Post not yet marked as solved
7 Replies
670 Views
Apple M2 Pro MacOs: 13.6 (22G120) In my system extension installer's postInstall script I have launch agent configured for the app as below: launchctl enable gui/$user_uid/com.mycompany.client.myproduct launchctl bootstrap gui/501 /Library/LaunchAgents/com.mycompany.myproduct.plist When I install the software using a local user, the service works fine without any issue and the service is shown listed in 'launchctl list' command: % launchctl list | grep -i mycompany 84714 0 com.mycompany.client.myproduct But when I login using on the same machine using a AD (Active Directory) user, the service/agent doesnt start and I don't see any entry service listed in 'launchctl list'. This is how my plist file looks like: % defaults read /Library/LaunchAgents/com.mycompany.myproduct.plist { CFBundleVersion = "200.200.200.200"; KeepAlive = 1; Label = "com.mycompany.client.myproduct"; LimitLoadToSessionType = ( Aqua ); ProgramArguments = ( "/Applications/mycompany.app/Contents/MacOS/Mycompany Module" ); RunAtLoad = 1; Version = "200.200.200.200"; } What am I missing here?
Posted
by
Post not yet marked as solved
3 Replies
597 Views
Hi, I have installed content filter network extension which is almost same as https://developer.apple.com/documentation/networkextension/filtering_network_traffic. I have another app. As part of this app, I am sending messages from server process to client process by using unix domain sockets which is almost same as https://github.com/devlights/go-unix-domain-socket-example. If network traffic is little bit more then my client is failing to send messages with write: no buffer space available error. If I stop content filter network extension then there is no issue. How can I handle this type of error with network extension? Note: This is happening on both monterey and ventura mac os (both intel and m1).
Posted
by
Post marked as solved
2 Replies
702 Views
Setup Details: Apple M2 Pro MacOs: 13.6 (22G120) My machine came back from sleep at 9:25am. At 9:57am packet tunnel stopped, I could find below logs: 2023-11-08 09:57:51.812259+0530 0x72ad Default 0x4adb 261 0 nesessionmanager: [com.apple.networkextension:] NESMVPNSession[Primary Tunnel:mycompany myproduct VPN:22FD4FD4-3E93-446F-961B-BFAE92561DD2:(null)]: Received a stop command from SystemUIServer[604] with reason 1 2023-11-08 09:57:52.115967+0530 0x6d02 Default 0x0 796 0 com.mycompany.client.mycompany-Client.myproductui.myproductpkttunnel: (NetworkExtension) [com.apple.networkextension:] [Extension com.mycompany.client.mycompany-Client.myproductui]: Calling stopTunnelWithReason because: Stop command received Can someone please help in understand: Why would 'SystemUIServer' trigger a stop command for my packet tunnel vpn with any user action? filtered.log full_logs.log
Posted
by
Post marked as solved
2 Replies
559 Views
A few weeks ago I had problems with provisioning profiles for some macOS programs, so I deleted/revoked a bunch of certificates and provisioning profiles and started from scratch. (Everything seems to be working for me) Unfortunately, a co-worker had two programs on his machine that were built with the old, test provisioning profiles with the revoked certificates, and it seems this may be preventing him from deleting the system extensions. The apps have been deleted, but that does not delete the system extensions. I installed a new program that programmatically (tries to) uninstall the system extension, but it doesn't seem to work either. When he reboots his computer, macOS pops up a window showing that the extensions may be malware. If he clicks "Show in Finder" and then tries to delete the system extensions from the Finder, he gets the message: The operation can't be completed because you don't have permission to access some of the items. Is it possible to delete the old system extensions that were installed with the old provisioning profiles? Are there multiple files that need to be deleted (e.g., the system extension and a .plist file somewhere)?
Posted
by
Post not yet marked as solved
4 Replies
377 Views
I have two System extensions in my application. App proxy provider ( app-proxy-provider-systemextension) Endpoint Security (com.apple.developer.endpoint-security.client) But now, on one of my customer's computer, when it launched app proxy provider, the sysextd process said that /Applications/XXXXXX.app/Contents/Library/SystemExtensions/com.***.AppProxy.systemextension: entitlement com.apple.developer.endpoint-security.client not present or not true. As a network system extension, my app proxy provider was asking for an Endpoint Security entitlement, that is a very strange. I don't know how to debug it. Any ideas and help?
Posted
by
Post not yet marked as solved
5 Replies
742 Views
I am currently writing an agent for endpoint security. I cannot connect the application and the xpc service. I start the plist with launchctl and then open the application, but it does not connect and the application runs dysfunctionally. I leave the code of the ViewController in the application and the XPCConnection in the xpc service below. Note: I create the XPC service in Xcode like a normal application and write it as a service application with "Application is background only" ViewController.swift func establishConnection() { XPCConnection.shared.connectToDaemon(bundle: Bundle.main, delegate: self) { success in DispatchQueue.main.async { [self] in if !success { controlButton.isEnabled = false configMenuStatus(start: false, stop: false) alertWithError(error: "Unable to start monitoring for broken connection with daemon.") } else { Logger(.Info, "Connect to daemon successfully.") } } } } XPCConnection.swift func connectToDaemon(bundle: Bundle, delegate: ClientXPCProtocol, handler: @escaping (Bool) -> Void) { guard connection == nil else { Logger(.Info, "Client already connected.") handler(true) return } guard getMachServiceName(from: bundle) == ClientBundle else { handler(false) return } let newConnection = NSXPCConnection(machServiceName: DaemonBundle) newConnection.exportedObject = delegate newConnection.exportedInterface = NSXPCInterface(with: ClientXPCProtocol.self) newConnection.remoteObjectInterface = NSXPCInterface(with: DaemonXPCProtocol.self) newConnection.invalidationHandler = { self.connection = nil Logger(.Info, "Daemon disconnected.") handler(false) } newConnection.interruptionHandler = { self.connection = nil Logger(.Error, "Daemon interrupted.") handler(false) } connection = newConnection newConnection.resume() let proxy = newConnection.remoteObjectProxyWithErrorHandler { error in Logger(.Error, "Failed to connect with error [\(error)]") self.connection?.invalidate() self.connection = nil handler(false) } as? DaemonXPCProtocol proxy!.connectResponse(handler) handler(true) } This is the error photo, the application continues to work First, I checked to see if I had made a mistake in the bundle identifier, but I could not find an error, and then I realized that I had not run the launchd service. Then I ran it, but it did not make any sense. What I am trying to do is to connect and run the network extension and endpoint security with this service, but the xpc service does not connect to each other.
Posted
by
Post not yet marked as solved
4 Replies
542 Views
I have an app that installs an endpoint system extension, and I have the app notarized. I can install the endpoint system extension and enable Full Disk Access fine on Ventura, Apple Silicon Sonoma, Apple Silicon But I cannot enable Full Disk Access on Ventura, Intel In System Settings, when I try to slide toggle switch on to enable full disk access, the toggle slides right back to off. In previous development versions, I could enable Full Disk Access on the Intel machine. Any idea why I cannot enable Full Disk Access on Ventura/Intel for my endpoint system extension in my notarized app? One additional observation, the name displayed in the Full Disk Access section is different between the Apple Silicon and Intel Macs. On Apple Silicon, only the final part of the Bundle ID is shown in Full Disk Access: endpointagent On Intel, the full Bundle ID is shown: com.MyCompany.MyApp.endpointagent Don't know if it matters, but I thought I'd point that out.
Posted
by
Post marked as solved
2 Replies
633 Views
I have an endpoint system extension that monitors exec system calls. It works fine, but I have to follow a very specific order when installing it. When I (the user) click to install, I get the option to open System Settings. There, I am presented with an option to "Allow" the endpoint application. If I: (1) click "Allow" and then (2) enable full disk access The application runs but doesn't get exec events. Console shows the error message Failed to open service: 0xe00002d8: Caller lacks TCC authorization for Full Disk Access Even after enabling full disk access (after allowing the extension to be installed), I do not get the exec events. To resolve this, I have to uninstall the endpoint system extension and reinstall it. (Note: If I first grant full disk access and then allow the endpoint system extension to be installed, everything works fine, but I suspect most users will now follow this happy path.) Is there a way to smooth this out, so that once full disk access is granted, the endpoint system extension gets events without needing to uninstall and reinstall the endpoint agent?
Posted
by
Post not yet marked as solved
1 Replies
647 Views
Hello , We've developed a MacOS app with a system extension that includes a content filter using socket and packet providers. To enable the extension, we applied the following payload : - <dict> <key>PayloadContent</key> <array> <dict> <key>PayloadIdentifier</key> <string>com.companyname.webcontentfilter</string> <key>PayloadType</key> <string>com.apple.webcontent-filter</string> <key>PayloadUUID</key> <string>5e8794fb-8820-43cd-9d18-d171539f755a</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadScope</key> <string>System</string> <key>AutoFilterEnabled</key> <false /> <key>FilterBrowsers</key> <true/> <key>FilterSockets</key> <true/> <key>FilterType</key> <string>Plugin</string> <key>FilterPackets</key> <true/> <key>FilterPacketProviderBundleIdentifier</key> <string>com.companyname.dlp.test1.ne.Extension</string> </dict> </array> <key>PayloadDescription</key> <string>Description</string> <key>PayloadDisplayName</key> <string>Restriction Profile</string> <key>PayloadIdentifier</key> <string>com.test.restriction</string> <key>PayloadOrganization</key> <string>COMPANY NAME Pvt. Ltd.</string> <key>PayloadRemovalDisallowed</key> <false/> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>f5f02ca0-0bed-4844-ba53-ea1e0dd6f61e</string> <key>PayloadVersion</key> <integer>1</integer> </dict> However, it failed to deploy on the device with the reason being: "The ‘VPN Service’ payload could not be installed. The VPN service could not be created." We've followed the guidelines from available resources, but it's not working as expected. Additionally, we're primarily testing on Ventura (M1) and Monterey (Intel). Any insights or advice from your side would be greatly appreciated. Thank you.
Posted
by
Post not yet marked as solved
3 Replies
915 Views
On Ventura - We have a network extension(Transparent Proxy) which blocks IPv6 traffic as below. override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { //Ipv6 gets blocks by below code let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Connection Refused"]) flow.closeReadWithError(error) flow.closeWriteWithError(error) On IPv6 enabled client machine, when a client application(Browser, curl, Teams etc), try to send HTTP/s requests, first they try to send the request over IPv6 and if it fails, they try with IPv4 (Happy eyeballs Algorithm) In our case, as network extension blocks IPv6 traffic, client applications will fail to establish connection over IPv6 and fallback to IPv4 as per Happy eyeballs Algorithm The above scenario works fine till MacOS Ventura. For Sonoma, this behaviour seems to have changed When our network extension blocks IPv6 traffic, client applications do not fallback to IPv4. They simply fail without trying IPv4. We tested with curl, Google chrome browser, Microsoft Teams. All these fail to load pages on Sonoma and they work fine on Ventura. Note : No change in our network extension code, curl and browser versions. Only change is MacOS version Please find attached screenshots with Ventura and with Sonoma, running curl One other difference seen here is the error code received by client applications with Ventura and Sonoma. On Ventura, when IPv6 is blocked, error is Network is down and client application establishes connection with IPv4. On Sonoma, error code is 22 : Invalid arguments and client application does not retry with IPv4. Curl_Ventura.jpg Curl_Sonoma.png
Posted
by
Post not yet marked as solved
6 Replies
552 Views
I'm testing my NEFilterDataProvider system extension by building it in Xcode and then copying the built app into the Applications folder. When I do changes to the extension's code, obviously the system extension process currently running needs to be shut down or restarted when I launch the new app version. Increasing the app version and build numbers each time always seem to trigger the system extension update in macOS, but that's not so convenient and at the latest when publishing the update those numbers cannot just make arbitrary jumps. I've read that moving an app to the trash should uninstall any attached system extensions, and this seems to be confirmed by the alert that macOS shows when doing so, but even after clicking Continue and authenticating with Touch ID to confirm the uninstall and emptying the trash, it sometimes happens that when launching the next version of my app from the Applications folder the old system extension is still running, which I notice e.g. because the app crashes since it's using different IPC method signatures than the system extension. When checking in Activity Monitor the system extension is also still listed. Even restarting the Mac doesn't always solve the issue, so when this happens my only solution is to increase the build and version numbers to make it work, and then reset them later when moving the app to the trash correctly uninstalls the system extension again. Is this a bug or am I missing something? Or is there a workaround that doesn't involve booting into safe mode and manually uninstalling the system extension? P.S.: I just tried booting into safe mode and moving the files from /Library/SystemExtensions to the trash as suggested on discussions.apple.com, but I got an alert saying that I didn't have the privileges to do so.
Posted
by
Post not yet marked as solved
1 Replies
426 Views
I am playing around with Endpoint Security using demo code. I tried to handle AUTH open event on specific folder in my Desktop,set to deny all, but whenever I set this extension, I successfully get deny all on the folder as well as all other files and documents in the Users space. static void handle_open_worker(es_client_t *client, const es_message_t *msg) { static const char *test_nnn = "/Users/myname/Desktop/endpoint_test/block_this_folder/"; static const size_t nnn_length = sizeof(test_nnn) - 1; if (strncmp(msg->event.open.file->path.data, test_nnn, nnn_length) == 0) { es_respond_flags_result(client, msg, 0, true); } else { // Allow everything else... es_respond_flags_result(client, msg, 0xffffffff, true); } } why the code applies to all other files rather than only deny open on /Users/myname/Desktop/endpoint_test/block_this_folder/
Posted
by
Post marked as solved
1 Replies
495 Views
Hi, AFAIK Safari or any macOS apps which uses WKWebview, uses com.apple.WebKit.Networking.xpc to do actual networking. I am working on a packet tunnel, where I am able to get process id associated with packet read. Based on process id, i am using libproc to get process name. I am facing below problem: For Safari or any other apps which uses WKWebview having same process name: com.apple.WebKit.Networking Any ways to distinguish wether it is from safari or other xyz wkwebview apps? Related Problem: https://developer.apple.com/forums/thread/693528 In this thread, app proxy can help but in packet tunnel no such options exposed.
Posted
by