Add RAND_set_urandom_fd.

Chromium uses a zygote process and a sandbox on Linux. In order for RAND_bytes
to be functional and guaranteed fork-safe inside the renderers, /dev/urandom
must be prewarmed. Calling RAND_bytes initializes a thread-local ChaCha20 key
when rdrand is available. So that key is fork-safe and to avoid tempting any
dragons by touching pthreads APIs before a non-exec fork, add a
RAND_set_urandom_fd API. It allows the consumer to supply the /dev/urandom fd
and promises to be fork-safe, both in initializing key material and use of
pthreads.

This doesn't affect any current shipping versions of Chrome.

BUG=462040

Change-Id: I1037e21e525918971380e4ea1371703c8237a0b0
Reviewed-on: https://boringssl-review.googlesource.com/5302
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2015-06-30 13:52:59 -04:00 committed by Adam Langley
parent daeafc22c6
commit de24aadc5b
2 changed files with 28 additions and 0 deletions

View File

@ -118,6 +118,19 @@ void RAND_cleanup(void) {
CRYPTO_STATIC_MUTEX_unlock(&global_lock); CRYPTO_STATIC_MUTEX_unlock(&global_lock);
} }
void RAND_set_urandom_fd(int fd) {
CRYPTO_STATIC_MUTEX_lock_write(&global_lock);
if (urandom_fd != -2) {
/* |RAND_set_urandom_fd| may not be called after the RNG is used. */
abort();
}
urandom_fd = dup(fd);
if (urandom_fd < 0) {
abort();
}
CRYPTO_STATIC_MUTEX_unlock(&global_lock);
}
/* read_full reads exactly |len| bytes from |fd| into |out| and returns 1. In /* read_full reads exactly |len| bytes from |fd| into |out| and returns 1. In
* the case of an error it returns 0. */ * the case of an error it returns 0. */
static char read_full(int fd, uint8_t *out, size_t len) { static char read_full(int fd, uint8_t *out, size_t len) {

View File

@ -33,6 +33,21 @@ OPENSSL_EXPORT int RAND_bytes(uint8_t *buf, size_t len);
OPENSSL_EXPORT void RAND_cleanup(void); OPENSSL_EXPORT void RAND_cleanup(void);
/* Obscure functions. */
#if !defined(OPENSSL_WINDOWS)
/* RAND_set_urandom_fd causes the module to use a copy of |fd| for system
* randomness rather opening /dev/urandom internally. The caller retains
* ownership of |fd| and is at liberty to close it at any time. This is useful
* if, due to a sandbox, /dev/urandom isn't available. If used, it must be
* called before |RAND_bytes| is called in the current address space.
*
* |RAND_set_urandom_fd| does not buffer any entropy, so it is safe to call
* |fork| between |RAND_set_urandom_fd| and the first call to |RAND_bytes|. */
OPENSSL_EXPORT void RAND_set_urandom_fd(int fd);
#endif
/* Deprecated functions */ /* Deprecated functions */
/* RAND_pseudo_bytes is a wrapper around |RAND_bytes|. */ /* RAND_pseudo_bytes is a wrapper around |RAND_bytes|. */