Hi,team:
I have configured SystemExtensions and WebContentFilter for supervised devices through mdm, and set NonRemovableFromUISystemExtensions in SystemExtensions, but found that my network filter cannot be deleted in macOS10, macOS11 and macOS12, but it can still be turned off by selecting the network filter in the network and choosing to disable the service. However, it cannot be turned off in macOS13, macOS14 and macOS15. How can I prevent supervised devices from turning off the network filter in 10, 11 and 12?
The macOS 10.15.7 image is as follows:
macOS15.1.1 cannot delete and cannot close the image as follows:
Hope to receive your reply!
System Extensions
RSS for tagInstall and manage user space code that extends the capabilities of macOS using System Extensions.
Posts under System Extensions tag
125 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hi,team:
I know that the MDM system extension configuration parameter RemovableSystemExtensions can only be valid after macOS12+, but can I also use this parameter between macOS10.15-12? Even if he is ineffective. Will this cause any problems with the system. I want to use the same MDM configuration file for the devices I manage, which have systems between macOS10.15-15.I hope to receive your confirmation
We are developing a tunnel based on transparent proxy system extension. We want to be able to decide whether to handle certain TCP flows based on FQDN.
So, is there a way to peek into TCPFlow data like we can in ContentFilter which will allow use to parse and check for SNI or Host-header?
As far as I understand, we can read data from flows until we have returned a decision from handleNewFlow.
Hi,
For one our requirement sendProviderMessage is been used to send some event/message from app to system extension, In my requirement, responseHandler in system extension would get explicitly called approximately after 1 min due to some async download file task.
But observing some strange behavior that responseHandler is getting called implicitly after ~20-30 seconds even before the code hit the place where its called explicitly. And that is the only place I'm calling responseHandler.
Can somebody please help about this strange behavior, Is there any implicit timeout interval associated with the responseHandler.
Thanks & Regards,
Preethi
After sending the app archive to apple notarization services, I received the following error: "The signature of the binary is invalid". This error is shown for both the arm64 and x86_64 builds of the app.
Some details about the project:
I have been able to notarize the app in the past, with the latest successful notarization at the start of October.
The organization does have a valid developer membership.
The app has no new dependencies since the last successful notarization.
The project uses automatic managed signing (no visible errors in xcode).
What has changed in app and development environment since the last notarization:
Updated macOS to macOS 15.
Updated to use new Xcode version (16)
The organizations membership did expire for a bit, but is now valid.
Changed apps target macOS version from 12.3 -> 13.5.
What I've tried to debug / resolve this issue:
Clean build folder and re-create archive.
Waiting a period of time and retrying the notarization.
Toggling 'automatic managed signing' off and on.
Tried to look through profiles, provisions, certs to see any issues.
Debug the issue with 'codesign -vvv --deep --strict /path/to/binary/or/bundle' CLI command (output said binary was valid). (https://developer.apple.com/documentation/security/resolving-common-notarization-issues)
Going back to last successful notarized commit and re-notarizing from that point, but that failed as well (changed version number).
Reverted a change of increasing the target macOS version (12.3 -> 13.5).
Compare failed notarization app's info.plist to previous info.plist for any obvious errors.
I tried to install the previous Xcode version, but it seems to be incompatible with macOS 15.
Tried looking online for any other options, but only found a couple similar issues and the suggestions I already tried.
I can provide further information if needed.
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
I've implemented a custom VPN for macOS (system extension, Packet Tunnel Provider, Developer ID). My tunneling logic uses BSD sockets.
My VPN is configured with on-demand and should always connect when there's traffic:
targetManager?.isOnDemandEnabled = true
targetManager?.onDemandRules = [NEOnDemandRuleConnect()]
I have encountered some issues when the device enters sleep (or waking up from sleep). I've tried two scenarios.
Scenario 1:
protocolConfiguration?.disconnectOnSleep = true
With this flag set, the OS will disconnect the VPN just before entering to sleep. However, there were cases when the OS disconnected the VPN but immediately restarted it - probably because of how I defined the on-demand rules. This resulted in the VPN disconnection, then trying to reconnect, and then the Mac entered sleep.
When the Mac woke up, the VPN didn't work well.
Is there a way to avoid waking up, just before the Mac enters sleep?
Scenario 2:
protocolConfiguration?.disconnectOnSleep = false
Disconnect on sleep is unset, and I've implemented the sleep/wake functions at the provider.
With this configuration, the OS won't disconnect the VPN, so even in sleep, the extension should stay 'alive,' so it won't have the problem from (1).
But in this case, I had other problems:
On sleep, I'm disconnecting the tunnel. But sometimes, on wake(), all my network calls fail. Are the interfaces still down? How can I detect this case from the system extension?
Is it possible that the OS would call sleep and then quickly call wake?
Is it possible that after sleep, the OS would call the startTunnelWithOptions() function?
Is it possible to restart the extension from a clean state right from the wake() function?
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?
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.
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?
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
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.
Hi,
I'm adding a Content Filtering (FilterDataProvider) on macOS to an existing app and using MDM to avoid user interaction.
I start by pushing the following payloads to my machine:
com.apple.system-extension-policy
com.apple.webcontent-filter
And then installing notarized pkg containing my app and the NE.
Inspecting the system logs shows the following error:
neagent Failed to find a com.apple.networkextension.filter-data extension inside of app com.company_name.app_name.daemon
And calling
submit(request: .activationRequest(forExtensionWithIdentifier: bundleId, queue: queue))
results in:
Missing entitlement com.apple.developer.system-extension.install
Installing from Xcode on a SIP disabled machine works fine and both NE and CF are working as expected.
I followed the steps mentioned here https://developer.apple.com/forums/thread/737894 however the embedded entitlements already contained -systemextension suffix so I'm not sure if re signing and the subsequent steps are needed.
I also double checked that com.apple.developer.system-extension.install is present, certificates are not expired and that get-task-allow is not present in the embedded profile.
Here is what my release entitlement file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>content-filter-provider-systemextension</string>
</array>
<key>com.apple.security.application-groups</key>
<array>
<string>com.company_name.app_name.network-extension.content-filter</string>
</array>
</dict>
and my release app entitlement:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.endpoint-security.client</key>
<true/>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>content-filter-provider-systemextension</string>
</array>
<key>com.apple.developer.system-extension.install</key>
<true/>
</dict>
</plist>
redacted logs
@eskimo may I ask for your help here!
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?
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?
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!
I'm working on a system extension leveraging endpoint security entitlement. However, while in development, is there a way to continue working and testing locally without having the endpoint security entitlement approved or needing the extension signed.
I got these errors running a build:
Provisioning profile "Mac Team Provisioning Profile: "com.xxxxx.extension" doesn't include the com.apple.developer.endpoint-security.client entitlement.
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);
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.
I have a need to do a coverage test for the networkextension function code implemented by the system extension, but I don't know how to implement this method.
For example, how do you use gtest or how do you use xctest to achieve these capabilities?
If you know, please let me know. Thanks