[Cryptography] WIPEONFORK in Linux 4.14

Florian Weimer fw at deneb.enyo.de
Mon Nov 27 14:02:11 EST 2017

* Nico Williams:

> pthread_atfork() suffices for fork-safety for userland PRNGs,

This is not true on Linux once you have code that calls fork/clone
system calls directly (which is traditional for namespace/container
setup, although it shouldn't strictly be necessary anymore).
pthread_atfork won't be called in these cases because it's strictly a
userspace thing.

What should work as an MADV_WIPEONFORK replacement is a MAP_SHARED
mapping and two counters, one on the mapping and one outside of it (in
regular, MAP_PRIVATE memory), and a lock covering both.  Around each
for-protected operation, you acquire the lock, check both pointers for
quality, increment both (the one on the MAP_SHARED mapping needs
atomic increment), and release the lock.  You need to do this before
and after the operation; the operation itself does not have to be
under the lock.

If the two counters diverge, you need to reinitialize: replace the
mapping and reset the counters (under the same lock), and retry the
operation if the second check failed.  This happens in both the parent
and the child process, eventually, but it it should be rare and not
contribute too much to the overall cost of forking.

At least for PRNGs, where you can retry as often as you want, this
looks promising to me.  I expect this to be much more reliable than
getpid/time/gettimeofday calls, and also much faster as long as the
lock is not contended.

With MADV_WIPEONFORK, you don't need to acquire the lock as long as
the mapping has not been zeroed, which avoids the lock contention and
any writes to globally shared data during regular operation.

More information about the cryptography mailing list