Is it possible to get PID from flow?

For each flow that gets to NEAppProxyProvider via handleNewFlow we can get metaData.
metaData has sourceAppAuditToken. Is it possible to use it to get PID or user ID?
Answered by DTS Engineer in 643052022
You can get a pid from an audit token using audit_token_to_pid.

Having said that, this is generally a bad idea pids can wrap. What do you plan to do with this pid? If you can use an audit token instead, that’d be better.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Accepted Answer
You can get a pid from an audit token using audit_token_to_pid.

Having said that, this is generally a bad idea pids can wrap. What do you plan to do with this pid? If you can use an audit token instead, that’d be better.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Thank you for the help! This function works perfectly.

What do you plan to do with this pid? 

We use it to get process name that opens the flow. Normally we use sourceAppSigningIdentifier, but it is empty for non-signed programs. Some users still have them.

Normally we use sourceAppSigningIdentifier, but it is empty for
non-signed programs. Some users still have them.

Indeed. This is a perfect example of why Apple silicon Macs require that all code be signed, even if it’s only ad hoc signed. It reduces the number of weird edge cases you have to deal with.

We use it to get process name that opens the flow.

That’s not the best way to approach this. Rather, use the audit token to create a code object (SecCodeCopyGuestWithAttributes) and then use that to get the path to the code (SecCodeCopyPath). That’s not truly secure — without a code signature you can’t reliably identify code — but it avoids the pid wrapping problem.

Here’s a code snippet:

Code Block
let atData: Data = … the audit token as bytes …
var codeQ: SecCode? = nil
var err = SecCodeCopyGuestWithAttributes(nil, [
kSecGuestAttributeAudit: atData,
] as NSDictionary, [], &codeQ)
assert(err == errSecSuccess)
let code = codeQ!
var staticCodeQ: SecStaticCode? = nil
err = SecCodeCopyStaticCode(code, [], &staticCodeQ)
assert(err == errSecSuccess)
let staticCode = staticCodeQ!
var codeURLQ: CFURL? = nil
err = SecCodeCopyPath(staticCode, [], &codeURLQ)
assert(err == errSecSuccess)
let codeURL = codeURLQ! as URL


Note that in Swift I have to get the static code from the code, whereas in C-based languages you can treat SecCode as a ‘subclass’ of SecStaticCode.

Share and Enjoy

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

That’s not the best way to approach this. Rather, use the audit token to create a code object (SecCodeCopyGuestWithAttributes) and then use that to get the path to the code (SecCodeCopyPath). 

We have faced an unexpected problem with this approach.

Apparently, SecCodeCopyGuestWithAttributes has to deal with sandbox when working with the attributes of other programs. That’s OK when programs are located in /Applications. But some programs including built-in ones like /usr/libexec/routined are in other locations. So, when SecCodeCopyGuestWithAttributes is called for them, sandbox just kills the network extension completely!

2021-06-04 09:10:47.927841+0800 0x4cd Error 0x0 147 0 sandboxd: [com.apple.sandbox.reporting:violation] Sandbox: com.initex.proxi(897) deny(1) file-read-data /usr/libexec/routined Violation: deny(1) file-read-data /usr/libexec/routine

Is there a way to fix this?

For obvious reasons, the com.apple.security.temporary-exception.files.absolute-path.read-only trick does not work because the path is not known.

I think, this also creates a security risk. We saw a case when a program with a non-standard executable path just stopped network extension of an antivirus!

Is it possible to get PID from flow?
 
 
Q