Defining two XPC services in a single System Extension

I currently have two separate system extensions that I have to launch. One is a Content Filter system extension and the other is an Endpoint Security system extension.

Both define their own separate XPC services, The Endpoint Security system extension defines it through NSEndpointSecurityMachServiceName and the Content Filter system extension through NetworkExtension -> NEMachServiceName.

Due to the complicated process of having the user approve two extensions and remove two extensions on uninstall, I'm venturing down the path of combining the two into a single extension. In the interest of reducing the amount of code changes, I'm interested in keeping two XPC services in the one system extension.

However, when I combine the code and then the plists to define both XPC services, I fail to create the XPC listener for the Endpoint Security mach service.

Is what I'm doing possible? Two XPC services in a single extension? I'm not sure if there were extra restrictions now due to combining the content filter and EndpointSecurity but it looks like simply migrating the exact same keys and values over to create two XPC services does not work.

However, when I combine the code and then the plists to define both
XPC services, I fail to create the XPC listener for the Endpoint
Security mach service.

Is this on 10.15.x? Or 11 beta?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Is this on 10.15.x? Or 11 beta?

This was on 10.15.4. Have not tried in 11 beta or later versions of 10.15.


This was on 10.15.4.

OK. My next step here would be to check whether launchd knows that the sysex is allowed to publish that service. You can do that with launchctl:

Code Block
% sudo launchctl procinfo ***


where *** is your process ID. I haven’t looked at this for a system extension specifically, but for a general launchd job you’ll see an endpoints list that describes each Mach service published by the job.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

OK. My next step here would be to check whether launchd knows that the sysex is allowed to publish that service. You can do that with launchctl:

Under a section with my bundle ID, I see:

Code Block
$(TEAMID).$(BUNDLEID) = {
active count = 3
        copy count = 0
        one shot = 0
        path = (submitted by smd.290)
        state = running
        program = /Library/SystemExtensions/063E252D-C01E-4EBE-96F5-1C5FA0650106/$(BUNDLEID).systemextension/Contents/MacOS/$(BUNDLEID)
        arguments = {
                $(BUNDLEID)
        }
        default environment = {
                PATH => /usr/bin:/bin:/usr/sbin:/sbin
        }
        environment = {
                XPC_SERVICE_NAME => $(TEAMID).$(BUNDLEID)
        }
        endpoints = { 
                "group.$(APP_BUNDLEID).content-filter-service" = { 
                        port = 0xb0ba7
                        active = 1 
                        managed = 1 
                        reset = 0 
                        hide = 0 
                }   
        }
...
}


So I see the Mach service for the content filter only. The service I had defined for the plist key NSEndpointSecurityMachServiceName is not available. It also follows a different naming convention though, $(TEAMID).$(BUNDLEID).xpc. Not sure if that matters.

The service I had defined for the plist key
NSEndpointSecurityMachServiceName is not available.

Hmmm, that rules out the theory I was working on. At this point I’m out of ideas, and my only suggestion is that you open a DTS tech support incident so that I can dig into this in more depth.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
I've opened a TSI case, thanks for your help Quinn!
I wanted to share the results of my research. After digging into this in some detail, my conclusion is that this is working as expected. To quote the EndpointSecurity man page:

If ES extension is combined with a Network Extension, set the
NEMachServiceName key in the Info.plist.

So, if you have a combined ES and NE system extension then the Mach service provided by the NE side takes precedence.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Defining two XPC services in a single System Extension
 
 
Q