Startup order of daemon and Endpoint Security Client

Hello,

My project includes an Endpoint Security Client and a daemon that communicates with the ES client using NSXPCConnection. The daemon is launched by launchd thank to a plist file in /Library/LaunchDaemons.

As both processes are started by launchd I was wondering if there was a predetermined order in which they are started. For the moment based on the PID, the daemon seems to be starting before the EndpointSecurity client.
Is this startup order documented somewhere?

Thanks
Answered by mdolan in 630781022
Sorry for the late reply, been super busy.

Yes, I was seeing the same thing, launchd agent failing to connect at startup, until I did the early boot. Then I saw PIDs that didn't make sense, but looking at timestamps of messages I added, I saw that the system extension loaded and ran before the launchd process.

This was the comment I got back from Apple when I asked back in April:


PIDs are assigned at fork time, not exec time. When the ES kext knows there are early boot clients, it holds up the kernel thread performing the execve. So all binaries that would get exec'd (e.g. via Loginwindow, launchd loads, etc.), will all get a new pid - they just won't have code execute if they're non-platform binaries until the ES client connects and makes its first set of subscriptions (and, if they subscribed to AUTH EXEC, the client has the opportunity to DENY the exec from continuing). None of this has anything to do with lower numbered PIDs.


In general there is no defined startup order between launchd daemons. In the case of an ES sysex however, you have the option of starting before other third-party code. See the discussion of NSEndpointSecurityEarlyBoot in WWDC 2020 Session 10159 Build an Endpoint Security app.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
I had the same question a while ago. Even though a launchd app has a smaller PID than your system extension, the launchd app is blocked from running until the early boot extensions load. I confirmed this with log messages at startup in each and saw the timestamps.
@eskimo Thanks for your answer, somehow that part of the presentation didn't register with my brain. I will be sure to rewatch the whole thing!

@mdolan Thanks for your answer, if I understand you correctly you are saying that if I add the NSEndpointSecurityEarlyBoot to my Endpoint Security extension it will boot before the launchd daemon?
Right now I am connecting to the extension from my daemon and I can see that it fails a couple time before it can secure a communication channel (using NSXPCConnection and the initWithMachServiceName method). So I think that it is loading before the extension.

So I think that it is loading before the extension.

In the absence of an explicit dependency, the obvious one being NSEndpointSecurityEarlyBoot, these two items race.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Accepted Answer
Sorry for the late reply, been super busy.

Yes, I was seeing the same thing, launchd agent failing to connect at startup, until I did the early boot. Then I saw PIDs that didn't make sense, but looking at timestamps of messages I added, I saw that the system extension loaded and ran before the launchd process.

This was the comment I got back from Apple when I asked back in April:


PIDs are assigned at fork time, not exec time. When the ES kext knows there are early boot clients, it holds up the kernel thread performing the execve. So all binaries that would get exec'd (e.g. via Loginwindow, launchd loads, etc.), will all get a new pid - they just won't have code execute if they're non-platform binaries until the ES client connects and makes its first set of subscriptions (and, if they subscribed to AUTH EXEC, the client has the opportunity to DENY the exec from continuing). None of this has anything to do with lower numbered PIDs.


Thanks mdolan, I really appreciate the fact that you took the time to come back to this thread even if you were super busy.
I ended up adding NSEndpointSecurityEarlyBoot to my ES client plist. And managing my connection with my other daemon knowing that it will boot after the ES client.
Startup order of daemon and Endpoint Security Client
 
 
Q