System Extensions

RSS for tag

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

Posts under System Extensions tag

98 Posts

Post

Replies

Boosts

Views

Activity

Missing icon in system extension
My macOS app includes a system extension that is activated once the app is ran. The system extension requires Full Disk Access. When navigating to System Settings → Privacy & Security -> Full Disk Access, I can see my extension listed, but it has the default system "lego" icon, instead of my app's icon. My app icon is working fine everywhere else. I tried to add an Asset Catalog to my extension on Xcode and include the icon, but it didn't do anything. Is this the default behavior for extensions, or can you include an icon?
1
0
291
Dec ’24
Transparent Proxy: Enhancement Requests for setMetadata API
In our setup, our Transparent Proxy (call it TP1) funnels traffic to a helper process running on the same machine (call it Helper), which then actually sends out the traffic to the wider Internet. Now say there's another Transparent Proxy, TP2, on the same machine. Assuming TP1 gets hold of the traffic first, the sequence would look like so: Safari --> TP1 --> Helper --> TP2 We want to make it appear to TP2 that the incoming traffic is from Safari, rather than from the Helper process. We are aware of the Network framework's setMetadata API, but this does not look appropriate for us to use here. The Helper process is pre-existing Golang code, which at best can interface with "pure" (ie BSD) sockets-based C code. In order to use the setMetadata API, looks like we will need to rewrite the entire networking logic to use nw_connection_t (or similar) API, which is too much work, so is infeasible for us to use. Is there a way to make the setMetadata API work at a socket level? e.g., associate the metadata with a socket so that whatever data is sent out on the socket by the Helper will seem to TP2 to be coming from the desired source process. Assuming there isn't such a way, please consider this an Enhancement Request to make it so! Also, this reveals another complication: If and when this Enhancement is implemented, our own TP1 (which interepted the traffic in the first place) would end up thinking that the traffic is from Safari, so ends up re-intercepting it, causing a loop. Safari --> TP1 --> Helper (invokes setMetadata) --> TP1 --> Helper ... Which leads to the next Enhancement Request: Please extend the API to allow setting of the "last-hop" source process in addition to the original source application. If the last-hop source process info is set, our TP1 can query this property, see that it's coming from our own Helper process, and skip interception. In summary, here are the Enhancement Requests: Allow setMetadata API to work at a socket level Allow setting of "last-hop" source process in the metadata, in addition to the original source application More succinctly, please allow setting of metadata to cater to cases where the actual egress happens via a (different) helper process that uses pure C sockets based API. I have also filed this as a Feedback with Apple, at FB16048393.
2
4
371
Dec ’24
Crash in macOS Content Filter System Extension
Hi, One of our customers is seeing a crash in our Content Filter in our network system extension. We're kind of at a loss for the cause of this as only one specific person is running into this and we're not at all in the stacktrace, out of the hundreds of others deployed with our extension. It would be greatly appreciated if we could have any help in diagnosing this issue. Attached is the crash report, and below is the crashing stacktrace. If this crash log is not sufficient, I have many more from the customer that I can attatch here. crash.txt Thread 4 Crashed:: Dispatch queue: NEFilterExtensionProviderContext queue 0 libsystem_kernel.dylib 0x18cd4e600 __pthread_kill + 8 1 libsystem_pthread.dylib 0x18cd86f70 pthread_kill + 288 2 libsystem_c.dylib 0x18cc93908 abort + 128 3 libc++abi.dylib 0x18cd3d44c abort_message + 132 4 libc++abi.dylib 0x18cd2ba40 demangling_terminate_handler() + 348 5 libobjc.A.dylib 0x18c9d13e4 _objc_terminate() + 156 6 libc++abi.dylib 0x18cd3c710 std::__terminate(void (*)()) + 16 7 libc++abi.dylib 0x18cd3c6b4 std::terminate() + 108 8 libdispatch.dylib 0x18cbd466c _dispatch_client_callout + 40 9 libdispatch.dylib 0x18cbdbc60 _dispatch_lane_serial_drain + 744 10 libdispatch.dylib 0x18cbdc79c _dispatch_lane_invoke + 432 11 libdispatch.dylib 0x18cbe77e8 _dispatch_root_queue_drain_deferred_wlh + 288 12 libdispatch.dylib 0x18cbe7034 _dispatch_workloop_worker_thread + 540 13 libsystem_pthread.dylib 0x18cd833d8 _pthread_wqthread + 288 14 libsystem_pthread.dylib 0x18cd820f0 start_wqthread + 8
2
0
461
Dec ’24
Activating extensions using swift result unwanted callbacks
I am trying to activate two separate extensions through my (single) application. When activating the extensions I set delegates for both activations to know when they are up and running. // Start by activating the system extension activationRequest = OSSystemExtensionRequest.activationRequest(forExtensionWithIdentifier: extensionIdentifier, queue: DispatchQueue.global(qos: .default)) activationRequest!.delegate = self OSSystemExtensionManager.shared.submitRequest(activationRequest!) When setting the delegates I am using two different classes - so “self” means something different for each extension. Each delegate implements the following method: public func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) { And I see (by using os_log) that when enabling only one extension of the two, both of the “request: didFinishWithResult” get called. This was very strange to me because I was planning on acting upon an extension activation and interacting with it - but now I see that I get a callback to an extension as if it was activated although it was not. Is there something I am not taking under consideration or something I should do differently?
2
1
366
Dec ’24
MacBook peripherals malfunction after allowed Driver Extensions
Hi, I’m developing my own Pcie Ethernet driverkit. My Pcie Ethernet card connect on Razor Core X and connect to MacBook via thunderbolt 3. The Problem: Click Driver application and send activate system extension request, then go to System setting -> Privacy & Security, in Extension section ->click “allow” , the peripherals malfunction immediately after "allow" clicked and type in the password.I can't control all peripherals devices like touchpad, keyboard and all of thunderbolt ports. However, it can regain functionality after plugging and unplugging the device. results I expected: User approve Driver Extensions enable and all peripherals work normally and Ethernet Card works. Has anyone encountered this problem? maybe something wrong in "OSSystemExtensionRequestDelegate" but I have no idea how to fix it Please Help. My Xcode version is Version 15.3 (15E204a). Thanks
0
0
521
Nov ’24
SimpleFirewall from Filtering Network Traffic example not filtering traffic
I've been trying very unsuccessfully to get the Filtering Network Traffic example code to work. I've read many forum posts but I still wasn't able to figure it out. I download the example project and set my development team for both targets. From then on the project is configured to create unique bundle identifiers and app group. Signing and provisioning profile is created and managed by Xcode with all the necessary entitlements. I am able to build the app (debug with provisioning profile) and then copy it to /Applications. I open the app, click start, enable and allow the network extension. Activity Monitor shows that the extension is running. But when I test local connections to port 8888 nothing happens in the app, the connection are just allowed. I tested with the following setup: create a local webserver with python3 -m http.server 8888 and make a request via curl and the webbrowser normal tcp connection with nc (nc -l 8888 and nc localhost 8888) I added lots of logging and I can see that the startFilter method is called, but never the handleNewFlow method. The only error I see in Console is networkd_settings_read_from_file Sandbox is preventing this process from reading networkd settings file at "/Library/Preferences/com.apple.networkd.plist", please add an exception. but don't know what to do about that. I also read the debugging guide (very helpful). I'm used to jump through a lot of hoops with this stuff, but I can't figure out what the problem is.
3
0
511
Nov ’24
IOSurface with System Extensions
Hi All, I'm working on a camera system extension where the main app is supposed to transfer a video stream using IOSurface memory sharing to the cam extension. I have built a sample app that does contains all the logic, but without a camera extension. So I'm essentially using IOSurface to render a video in one SwiftUI view and show the result in another SwiftUI view. Just for testing purposes. And everything works fine so far. Now, when moving the receiver code to the camera extensions, I'm having problems in accessing the IOSurface via ID. I am sharing the IOSurface ID via UserDefaults. I know from the logs the ID is correctly transferred. Here is the code that uses IOSurfaceLookup to get the IOSurface. But this fails with the given message. The error message prints the surface ID which is the correct one. I know this from the main app where I get the ID and print it as well. private var surfaceId: Int = -1 { didSet { logger.info("surfaceId has changed") if surfaceId == -1 { stopReceivingFrames() ioSurface = nil } else { guard let surface = IOSurfaceLookup(IOSurfaceID(surfaceId)) else { logger.error("failed to lookup IOSurface with ID: \(self.surfaceId)") return } self.ioSurface = surface logger.info("surface set, now starting receiving frames") startReceivingFrames() } } } My gut feeling says that this issue might be related to some missing entitlement, sandboxing. In general, I have a working camera extension. I'm just not able to render a video in the main app, and send it over to the camera extension to overlay another web cam. Both, the main app and camera extension are in the same XCode workspace and share the same AppGroup. In short, my actual questions are: Is there any entitlement required for using IOSurface between app and camera system extension? Is using IOSurface actually possible in system extensions? Is there any specific setting/requirement that I need to handle to make this work?
0
1
585
Nov ’24
Query regarding transparent proxy provider NENetworkRule for port 53
We want to ressolve dns for predefined sets of private app domains. We've added this rule: NENetworkRule(destinationHost: NWHostEndpoint(hostname: Private Domain1(example.com), port: 53), protocol: .UDP) As per apple documentation: A rule that matches all DNS queries/responses for hosts in the example.com domain. do you think it will work i.e it will forward DNS requests UDP flow to transparent provider in all the cases? or do you think the text is a bit misleading. it should instead say: "A rule that matches all DNS queries/responses for nameservers in the example.com domain"? This rule that look for port 53 of that domain only works if the system really asks a nameserver of that specific domain, right? So, what if a local DNS server or a different nameserver are taking care of the resolution?
3
0
393
Nov ’24
Network Extension stopped working with SIP disabled
Whenever I'm working on my content filter for macOS, I usually keep SIP disabled and with developer mode on (systemextensionsctl) as a convenience. The issue: content filter stopped receiving any kind of traffic when SIP is disabled. I don't see any log lines in Console for new flows, and the filter can't block anything, since it doesn't get any flows. Issue started yesterday. I tried several things and did some investigation, here are some findings: Reboot: rebooting did not fix the issue (while keeping SIP disabled). Reenabling SIP fixes the issue for both App Store and Xcode builds. Code: latest published version also stopped working with SIP disabled. This version is stable and confirmed to work as reported by users. Clean Xcode + rebuild did not fix the issue. Lastly, I inspected the logs and did not see any errors standing out. I noticed the filter does get started (startFilter is called) and registered, but after that there are no errors/new flows or anything, just silence (logs below). com.apple.networkextension default 15:22:22.270746-0300 : Calling startFilterWithCompletionHandler com.extension.MyExtension info 15:22:22.270998-0300 Success applying filter settings com.apple.networkextension debug 15:22:22.272705-0300 NESMFilterSession[My Extension:B9F3F30E-E0E0-4E53-8B32-EFC285E3CF6A]: Checking providerBundleIdentifier com.extension.MyExtension for pluginClass 4 com.apple.networkextension debug 15:22:22.272717-0300 Checking for com.extension.MyExtension - com.apple.networkextension.filter-data com.apple.networkextension default 15:22:22.272728-0300 Found 1 registrations for com.extension.MyExtension (com.apple.networkextension.filter-data) com.apple.networkextension debug 15:22:22.272778-0300 NESMFilterSession[My Extension:B9F3F30E-E0E0-4E53-8B32-EFC285E3CF6A]: com.extension.MyExtension is registered for pluginClass 4 Here are some additional info about my system: macOS 15.1 Between yesterday and today, the only new Installation is XProtectPlistConfigData at 12:10AM Thanks!
7
0
680
Nov ’24
Can't NSUserDefaults be used between container apps and system extensions?
Hi, I try to use NSUserDefaults to share some parameter values ​​between the container app and the system extension. I have added the App Group in Signing & Capabilities in both apps. I set it in the container app and read it in the system extension app, but the information I read from the system extension is nil. I tested that I can read the information directly from the container app. Is the system extension running in the sandbox not allowed to read other app information? But the information I see should be OK, as shown below: The container app code is as follows: NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.yourcompany.shared"]; [sharedDefaults setObject:@"Sample Data" forKey:@"SharedData"]; [sharedDefaults synchronize]; The system expansion reading code is as follows: NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.yourcompany.shared"]; NSString *data = [sharedDefaults objectForKey:@"SharedData"]; os_log_debug(logHandle, "NSUserDefaults: %{public}@", data);
1
0
508
Nov ’24
WireGuard Apple VPN macOS 15.1 issue with connecting to VPN
I am working on developing a Mac app (WireGuard Apple VPN) that will be distributed outside the App Store. I have added the network extension which is included in the system extension with packet tunneling capability. I have created a build following these steps here: https://developer.apple.com/forums/thread/737894 as per your suggestions in my accepted post: https://developer.apple.com/forums/thread/761251 It works fine in this case when the machine has SIP disabled and systemextensionsctl developer enabled. As soon as I have made changes on the machine to disable systemextensionsctl developer and enable SIP, it loads the system extension and also asks for network extension permission. But it does not connect to the VPN. I have copied the app to the "/Applications" directory before opening it. This issue is specific to macOS 15.1. It works fine for macOS 14.* and 13.*. Speaking of macOS 15.0, it didn't work in both cases with SIP enabled or disabled. So, it seems that it must be a bug in macOS 15.0 and it seems that this bug was partially fixed in macOS 15.1. Is that right? I am currently planning to distribute the app to testers for final testing before rolling it out to a wider audience. Am I missing something? Thanks in advance.
6
0
1.8k
Nov ’24
Endpoint Security System Extension Limitations
Trying to flesh out an idea for an application which would rely on Endpoint Security Framework and Network Extension Framework, where intend the application to: Forward certain ESF events to a backend (on a separate server) Forward certain Unified logs to a backend (on a separate server) Forwarding various DNS queries and responses (on a separate server) Retrieve configuration from the backend to set Network Extension Filters Are there any limitations and/or reasons not to bundle all this functionality into a single system extension? I know of other applications where system extension is very thin and main application (daemon) communicates over xpc with the system extension, would this be considered best practice?
1
0
550
Oct ’24
macOS System Extension Compatibility Issues
We’re encountering issues with a system extension that subscribes to multiple events. Some users are experiencing performance problems when running our extension alongside other system extensions like Microsoft Defender and Crowdstrike, which seem to generate a high volume of events. However, on certain Macs with an identical setup, there are no performance issues, making it difficult to pinpoint the cause. Has anyone found ways to improve compatibility with other system extensions? Currently, we’re ignoring and caching events from other extensions to avoid unnecessary processing. The specific ES events contributing to the issue seem to be: • ES_EVENT_TYPE_AUTH_EXEC • ES_EVENT_TYPE_AUTH_OPEN I realize this is a broad question, but the documentation for endpoint security extensions is quite limited. Any insights or suggestions would be greatly appreciated!
1
0
582
Oct ’24
Launching Network System Extension from automated installation
We have network system extension which is fundamental part of our application and needs to be installed before the application can run. In many cases we need the installation to be automated, i.e. without logged-in user (with the help of MDM solution like JAMF). Is there a way to activate the extension fully automated without logged-in users? I tried to call 'open -W -a /Application/' from the package's post install script. But seems launch fails if no user is logged in.
1
0
385
Oct ’24
es_new_client failed due to app sandbox violation
I try to mix content filter and endpoint security in one system extension, but get error below when the program invoke es_new_client(returned ES_NEW_CLIENTRESULT_ERR_INTERNAL). Failed to open services: 0xe00002e2: Caller was denied connecting to the ES subsystem, possibly due to a sandbox violation. how to solve this error while keeping two functionalities in one system extension? or I have to seperate them?
1
0
532
Oct ’24
Kernel sends SIGKILL to process which is subscribed on ES_EVENT_TYPE_AUTH_OPEN
The kernel sends SIGKILL to application if it handles ES_EVENT_TYPE_AUTH_OPEN and lldb is attached to this process. App: int main(int /*argc*/, char** /*argv*/) { es_client_t *pEpClient = nullptr; es_new_client_result_t result = es_new_client(&pEpClient, ^(es_client_t *pClient, const es_message_t *pMessage) { switch (pMessage->event_type) { case ES_EVENT_TYPE_AUTH_OPEN: { uint32_t authorizedFlags = pMessage->event.open.fflag; if ((authorizedFlags & FREAD) || (authorizedFlags & FWRITE)) { std::filesystem::path filePath = std::string(pMessage->event.open.file->path.data, pMessage->event.open.file->path.length); std::string fileName = filePath.filename(); if (fileName == "test.txt") { std::cout << "blocked fileName: " << filePath.filename() << std::endl; authorizedFlags &= ~FWRITE; authorizedFlags &= ~FREAD; } } if (es_respond_flags_result(pClient, pMessage, authorizedFlags, false) != ES_RESPOND_RESULT_SUCCESS) { std::cout << "es_respond_flags_result() failed with error " << std::endl; } } break; default: break; } }); if (result != ES_NEW_CLIENT_RESULT_SUCCESS) { std::cout << "es_new_client() failed." << std::endl; return 1; } es_event_type_t eventsList[] = { ES_EVENT_TYPE_AUTH_OPEN }; if (es_subscribe(pEpClient, eventsList, 1) == ES_RETURN_ERROR) { std::cout << "es_subscribe() failed." << std::endl; } // wait int i = 0; std::cin >> i; if (es_delete_client(pEpClient) == ES_RETURN_ERROR) { std::cout << "es_delete_client() failed." << std::endl; } return 0; } (lldb) process attach --pid 61127 .... (lldb) c Process 61127 resuming Process 61127 exited with status = 9 (0x00000009) Terminated due to signal 9 System log: Allowing set_exception_ports from [debugserver] on [ep_sample] for entitled process/debugger Client did not respond in appropriate amount of time (client pid: 61127), sent SIGKILL
2
0
711
Oct ’24