How can 2 processes have the same PID, even if it is grandparent and grandchild? When I try killing a process using the PID, how the kernel know which to kill?
* PID 17519 forks producing a new process with PID 26606
* PID 17519 produces some "random" bytes then exits
* PID 26606 forks producing a new process with the now unused PID 17519
* New PID 17519 produces some "random" bytes, which will be the same as the "random" bytes produced by original PID 17519, causing a raptor to attack the user.
If I get a block from /dev/urandom, then another one at some later time, what are the chances it's identical? Isn't that what you're saying here (or was the whole post intended to be comical and not just the last line).
[If only it had been raining it would have taken days longer for the raptor to attack, or something /random]
The problem is that (Libre|Open)SSL doesn't use /dev/urandom directly and instead implements a CSPRNG in user-space (seeded from /dev/urandom). And then you need to be careful to reseed the CSPRNG after fork or you'll generate the same random number that the other process did.
You could mix in the parent's PID too, but that would only delay the problem (you'd need more layers of fork before triggering the shared-state bug again).
Why can't LibreSSL just open /dev/urandom once, on first call to RAND_poll/RAND_bytes/some-other-init-function, etc. and then always read from it directly. If that first open fails then you return an error from RAND_poll/RAND_bytes.
/dev/urandom is pretty slow on Linux. OpenSSL's CSPRNG is several times faster. On my workstation just now, I get 13MB/sec from /dev/urandom and 61MB/sec from OpenSSL's CSPRNG.
You can't just add the parent pid because that information is lost when the process's parent exits (the ppid becomes 1).
Note that the article calls out two entirely separate issues:
1) The PRNG wrapper apparently depends on the pid to "detect" if there's been a fork, and so the PRNG seed will remain the same in grandparent and grandchild if you double-fork and manage to get the same pid. This may or may not be a problem - whether or not you can induce enough forks to manage to get the right pid will depend on application. This is not dependent on
2) If both /dev/urandom and sysctl() is unavailable, it falls back on generating its own entropy using a convoluted loop and lots of sources. There's all kinds of ways that can be nasty, but that relies on enough factors that just getting the same pid would be insufficient in and of itself (but it may very well reduce the entropy).
I think the scenario here is that process X forks, creating process Y, then process X terminates, then process Y repeatedly forks until it creates a process Z with the same PID as X.