Access to process unique id

Hi Everyone,

In libproc, there is a flavour for proc_pidinfo() PROC_PIDUNIQIDENTIFIERINFO, which as the name suggests, returns a struct of values that uniquely identify a process - more reliably than a pid.

In particular, it seems to have a 64 bit value that appears to be unique forever (or at least until system restart), thus shouldn't suffer from pid reuse races.

The problem is that this interface is gated behind #ifdef PRIVATE, and as such is pretty much the antithesis of 'published api'. So I guess my question is, is there a 'legit' way of accessing this value (or an equivalent) ? The call seems to work fine, and the number appears unique..

thanks, nick

Answered by DTS Engineer in 886427022

So I guess my question remains - is there any other way to access this, and if not, is it possible to request that this become a public API?

So, there are a few different answers here:

  • What you're actually looking for is called an "audit token". I think PROC_PIDUNIQIDENTIFIERINFO is returning the audit token, but it's possible it's returning some other value derived from the audit token. Either way, you should be using the audit token, not PROC_PIDUNIQIDENTIFIERINFO.

  • As a general comment, the reason there isn't an obvious "audit token for PID" API is that this mapping process is inherently insecure— the primary reason audit tokens exist is to protect against PID reuse, but that also means the process of mapping a PID to an audit token is opening yourself to EXACTLY the attack audit tokens were created to defend against.

  • The more typical usage pattern is to retrieve the audit token of some existing object/connection (like a Mach port or an XPC connection), then use the audit token to retrieve other "information".

  • Having said that, even that case is not common, as most of our APIs tend to have higher-level mechanisms that are easier to use/more secure/etc. See this post about XPC validation for one example of this.

  • However, if you really want to get an audit token from a PID, this thread describes how to do so.

With all that context, let me jump back first to here:

So I guess my question remains - is there any other way to access this, and if not, is it possible to request that this become a public API?

I think the main question here is "what are you actually trying to do"?

Audit tokens are primarily used in lower-level system components that both need to track "lots" of processes AND aren't REALLY "interacting" with those processes. That last point is key because interactions between processes go over Mach/XPC, at which point the validations done in terms of the connection itself, not going back to the underlying process.

Similarly, I think part of the reason (aside from the obvious, "it would be a ton of work"...) is that using them as a security construct can be much trickier than it looks. For example, the EndpointSecurity API has its own structure it provides for describing processes. That structure includes the audit token but it also includes a number of code signing-related properties. That's mostly due to performance reasons, but also because the validation process itself has its own traps and pitfalls, since you can't just read the data off of disk (the running executable may already have been deleted).

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thanks for the post, this is a great post and hope many developers jump into this thread and provide suggestions and opinions of the best way to accomplish that.

proc_pidinfo() PROC_PIDUNIQIDENTIFIERINFO looks something I haven't use to be honest. Using them in production code sounds risky because is subject to breakage in future macOS/iOS updates without warning? If your concern about PID reuse races you should not use PIDs at all.

If you are iterating over running processes or monitoring a specific process and want to ensure the PID hasn't been reused by a new process, the standard approach is to combine the PID with the process's start time, it is practically impossible for a PID to be reused in the exact same microsecond.

Albert
  Worldwide Developer Relations.

Hi Albert,

Thanks for the info. I am aware of the pid+ctime trick. Whist I agree the odds of a pid being re-used in the same microsecond are practically impossible, clearly unique id was created for a reason.

I guess I was taken by the unique id function. It's a more elegant solution to the problem. It has been in Darwin in an almost unaltered form since 2013 with a comment saying /* This structure is API */.

So I guess my question remains - is there any other way to access this, and if not, is it possible to request that this become public api? It's already implemented and has tests, it really just needs to be moved to a public header.

thanks nick

Accepted Answer

@neek78 Brilliant coding skills and nice finding for sure.

Unfortunately, I do not have an answer about that becoming a public api, but I think will be worth for you to request an enhancement and get an answer.

If you'd like us to consider adding the necessary functionality, please file an enhancement request using Feedback Assistant. Once you file the request, please post the FB number here.

If you're not familiar with how to file enhancement requests, take a look at Bug Reporting: How and Why?

Good luck!

Albert
  Worldwide Developer Relations.

Thanks Albert - I opened FB22652617

@neek78 Thanks for doing that so quickly. Give the team sometime to look into it and I'm sure they'll give you an answer eventually.

For more details on when you'll see updates to your report, please see What to expect after submission.

Albert
  Worldwide Developer Relations.

So I guess my question remains - is there any other way to access this, and if not, is it possible to request that this become a public API?

So, there are a few different answers here:

  • What you're actually looking for is called an "audit token". I think PROC_PIDUNIQIDENTIFIERINFO is returning the audit token, but it's possible it's returning some other value derived from the audit token. Either way, you should be using the audit token, not PROC_PIDUNIQIDENTIFIERINFO.

  • As a general comment, the reason there isn't an obvious "audit token for PID" API is that this mapping process is inherently insecure— the primary reason audit tokens exist is to protect against PID reuse, but that also means the process of mapping a PID to an audit token is opening yourself to EXACTLY the attack audit tokens were created to defend against.

  • The more typical usage pattern is to retrieve the audit token of some existing object/connection (like a Mach port or an XPC connection), then use the audit token to retrieve other "information".

  • Having said that, even that case is not common, as most of our APIs tend to have higher-level mechanisms that are easier to use/more secure/etc. See this post about XPC validation for one example of this.

  • However, if you really want to get an audit token from a PID, this thread describes how to do so.

With all that context, let me jump back first to here:

So I guess my question remains - is there any other way to access this, and if not, is it possible to request that this become a public API?

I think the main question here is "what are you actually trying to do"?

Audit tokens are primarily used in lower-level system components that both need to track "lots" of processes AND aren't REALLY "interacting" with those processes. That last point is key because interactions between processes go over Mach/XPC, at which point the validations done in terms of the connection itself, not going back to the underlying process.

Similarly, I think part of the reason (aside from the obvious, "it would be a ton of work"...) is that using them as a security construct can be much trickier than it looks. For example, the EndpointSecurity API has its own structure it provides for describing processes. That structure includes the audit token but it also includes a number of code signing-related properties. That's mostly due to performance reasons, but also because the validation process itself has its own traps and pitfalls, since you can't just read the data off of disk (the running executable may already have been deleted).

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Access to process unique id
 
 
Q