Spawn Constraint example

I downloaded the sample code given in: https://developer.apple.com/documentation/servicemanagement/updating-your-app-package-installer-to-use-the-new-service-management-api?language=objc

Made necessary changes and I was able to install and test successfully.

Next, I watched: https://developer.apple.com/videos/play/wwdc2023/10266/

I noted the example given at: 14:52 Example launchd plist constraint. Applied the KeepAlive, RunAtLoad and SpawnConstraints parameters to the sample code downloaded earlier.

I got the log in the console and agent was not allowed: default 11:35:26.885483+0300 kernel AMFI: Launch Constraint Violation (enforcing), error info: c[5]p[1]m[1]e[0], (Constraint not matched) launching proc[vc: 10 pid: 19439]: /Library/Application Support/X/SMAppServiceSampleCode.app/Contents/Resources/SampleLaunchAgent, launch type 0, failure proc [vc: 10 pid: 19439]: /Library/Application Support/X/SMAppServiceSampleCode.app/Contents/Resources/SampleLaunchAgent

Is SpawnConstraint not applicable for launch agents? Since launchd is the only parent process that can spawn the launch agent based on the plist, is the example given at 14:52 still valid?

Answered by DTS Engineer in 801637022
The constraints seem to have been cached in the system.

If you’re worried about stuff being cached, my general advice is that you test in a VM, restoring from a ‘clean’ snapshot between each test.

Having said that, I’m not sure whether SpawnConstraint is the droid you’re looking for here. It exists to prevent substitution, that is:

  1. You install a launchd property list that references your executable.

  2. An attacker somehow replaces your executable with their own.

  3. The system then starts their executable rather than yours.

Most folks who ask about this stuff are trying to prevent their launchd job from being used by other folks. In that case, see Validating Signature Of XPC Process.

Share and Enjoy

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

The constraints seem to have been cached in the system.

  1. Remove the app per Readme of the sample code did not help.
  2. Re-build and re-install the package without constraints in the launch plist.
  3. Still the constraints violation is observed.

How to clear the constraints cache on macOS 14.6.1?

The constraints seem to have been cached in the system.

If you’re worried about stuff being cached, my general advice is that you test in a VM, restoring from a ‘clean’ snapshot between each test.

Having said that, I’m not sure whether SpawnConstraint is the droid you’re looking for here. It exists to prevent substitution, that is:

  1. You install a launchd property list that references your executable.

  2. An attacker somehow replaces your executable with their own.

  3. The system then starts their executable rather than yours.

Most folks who ask about this stuff are trying to prevent their launchd job from being used by other folks. In that case, see Validating Signature Of XPC Process.

Share and Enjoy

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

Thank you Qunn! I noted the link you have provided and I will explore them. However, I was inspired by the simplicity of XPCListener-XPCSession and I wanted to try that with Constraints as an alternative to NSXPCConnection with listener(_:shouldAcceptNewConnection:) delegate.

Is there,

  1. some document about how to use XPCPeerHandler?
  2. a way to get peer info from XPCListener.IncomingSessionRequest?

so that accept/reject can be given for the handler based on the peer's info.

Accepted Answer

AFAIK there’s no way to validate connections using the low-level Swift API.

Normally I’d suggest you file an enhancement request for such a thing, but in this case I think the XPC team already understands the importance of this (r. 132430549).

Share and Enjoy

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

Spawn Constraint example
 
 
Q