Hello, I had a question regarding random PID usage and implementation in OpenBSD. Sorry by advance if my question may seem obvious, but I did not manage to find any really satisfying answer.
I was reading an article (french magazine MISC issue 74) written by the author of CVE-2014-0016 (stunnel) and CVE-2014-0017 (libssh) affecting the random number generator used by the server to construct the hello cookie. These software were using the child process PID + a Unix timestamp as seed. The author demonstrated how, on systems using random PIDs, it was therefore easy to trick the system into generating two times the very same cookie (a very few minutes with an average of as few as 20 requests per second), thus giving the opportunity to deduce private keys thanks to some cryptographic magic out of scope here. On the other side, systems using a traditional sequential PID were practically not vulnerable to this attack since it would need to be able to remotely make the server cycle through all the available PID in less than a second. As per my understanding, random PID was implemented mostly in order to protect bogus application using the PID to generate temporary file names and other "race conditions" (cited by most sources without ever defining what kind of race condition they precisely mean). The example above show that it just does not prevent race conditions, actually it helps them, and while it protect against the locally exploitable temporary file name prediction it opens remotely exploitable flaws which seems worse. FreeBSD servers are particularly subject to such attacks because they generate really random PIDs, so it takes 3-4 minute in average with 20 requests per seconds to get the system generate two identical PID during the same second. OpenBSD, as a security conscious OS, has already implemented a protection against such exploit (cool :) !), but I'm surprised by the technical choices made here (less cool :( ). The protection has been added in the revision 1.150 (mid-2013) of the file `src/sys/kern/kern_fork.c'. It adds a array of a fixed and hardcoded size of 100 entries storing the lastly freed PIDs (`pid_t oldpids[100];'). So, blindly execute the 20 requests described in the article will indeed not work on a lowly loaded OpenBSD system. However, on a highly loaded system (whether the load results from genuine traffic or is part of the attack), this array will just become useless and OpenBSD falls as well as FreeBSD. Years ago (2003) Theo de Raadt wrote an email (http://www.monkey.org/openbsd/archive/misc/0301/msg00720.html) as part of a discussion related to PID randomization side-effects in which he mentions "At best, we could use some sort of high-bit non-repeating trick like we do with dns and ip id's". I suppose he was referring to what has been implemented in `src/sys/netinet/ip_id.c' ensuring that "an ID will not be reused for at least 32768 calls". I was wondering why this has never been implemented? At the first glance, this seem to be the safe and best way to do, isn't it? PID related security issues mainly seems to come from application wrongly assuming that: - PID are unguessable, - PID will not be reused quickly. IMHO PID full randomization as implemented in FreeBSD correctly addresses the first assumption, but heavily breaks the second one. A more clever partial randomization would address both aspects, effectively improving security for both local and remote attacks. The current small array of 100 entries seems quite weak to me, while the model based on IP id generation would seem more resistant but has nevertheless be left in profit of this small array... I suppose there must be a good reason behind this choice, but I do not manage to get it, would you help me to understand this? Thank you by advance, Best regards, Simon.