[draft] investigate solutions to immediate-reseeding-on-fork#1377
[draft] investigate solutions to immediate-reseeding-on-fork#1377dhardy wants to merge 2 commits intorust-random:masterfrom
Conversation
|
Honestly, I am tempted to say that let pid = unsafe { libc::fork() };
if pid == 0 {
thread_rng().reseed();
}We currently implement fork protection only for UNIX targets and I am not even sure it properly works on all Most Rust applications do not use |
Problem: such a call would need to appear immediately before every (important) usage of
Certainly, choosing not to provide fork protection is a valid choice. |
Maybe I misunderstand something, but I don't think so? You only need to assure that We could mention |
Ah, I didn't know this. Then, yes. In that case we could also fix the existing |
This is an investigation branch into potential solutions to #1362.
No fork protection
The simplest solution is simply to choose not provide fork protection.
GlobalRng
ThreadRnghas thread-local state which cannot be reached byfork_handler. The simplest "solution" to this is to replace thread-local state with global state that can be, henceGlobalRngusing aMutex.Perf. on a single thread is (unsurprisingly) fine, however holding onto a
GlobalRngreference could easily cause dead-locking, makingfn global_rng() -> GlobalRnga hazard.Obviously this is not a good solution where high-performance generation is needed from multiple threads; in this case users would need to seed and store local generators. This is possibly the best option in such a case anyway.
Implication:
global_rngis fine for occasional usage and/or in single-thread environments, but probably we would want to encourage users to construct a local RNG for any significant usage.An additional advantage of replacing
ThreadRngwith this is less thread-local state usage.Frequent polling of RESEEDING_RNG_FORK_COUNTER
The current fork handler works by checking
RESEEDING_RNG_FORK_COUNTERonly when generating a new block of random state. We could check this much more often (on every value generation), but this likely would have a large perf. hit.Other solutions?
There are various approaches to fast thread-safe containers and consensus algorithms. We could possibly attempt to design an RNG along such lines, however this would be far from a trivial undertaking (especially reviewing for security) and still likely to severely under-perform existing RNGs.
Maybe there are other existing solutions we're overlooking?