aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/rand/drbg_lib.c
diff options
context:
space:
mode:
authorDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>2019-05-27 21:03:09 +0200
committerDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>2019-09-11 11:22:18 +0200
commit849529257c9979c7ca0d28e8b80a47bc4a36d4f2 (patch)
tree2e85307b6e252fe6d175fae0bd8ca3282404e3d2 /crypto/rand/drbg_lib.c
parentdc64dc2edd215d6cc5843c1bfe1f0b64bff26adc (diff)
downloadopenssl-849529257c9979c7ca0d28e8b80a47bc4a36d4f2.tar.gz
drbg: ensure fork-safety without using a pthread_atfork handler
When the new OpenSSL CSPRNG was introduced in version 1.1.1, it was announced in the release notes that it would be fork-safe, which the old CSPRNG hadn't been. The fork-safety was implemented using a fork count, which was incremented by a pthread_atfork handler. Initially, this handler was enabled by default. Unfortunately, the default behaviour had to be changed for other reasons in commit b5319bdbd095, so the new OpenSSL CSPRNG failed to keep its promise. This commit restores the fork-safety using a different approach. It replaces the fork count by a fork id, which coincides with the process id on UNIX-like operating systems and is zero on other operating systems. It is used to detect when an automatic reseed after a fork is necessary. To prevent a future regression, it also adds a test to verify that the child reseeds after fork. CVE-2019-1549 Reviewed-by: Paul Dale <paul.dale@oracle.com> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9832)
Diffstat (limited to 'crypto/rand/drbg_lib.c')
-rw-r--r--crypto/rand/drbg_lib.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index f8b58d7245..c24222188f 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -415,7 +415,7 @@ static RAND_DRBG *rand_drbg_new(OPENSSL_CTX *ctx,
drbg->libctx = ctx;
drbg->secure = secure && CRYPTO_secure_allocated(drbg);
- drbg->fork_count = rand_fork_count;
+ drbg->fork_id = openssl_get_fork_id();
drbg->parent = parent;
if (parent == NULL) {
@@ -829,6 +829,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
int prediction_resistance,
const unsigned char *adin, size_t adinlen)
{
+ int fork_id;
int reseed_required = 0;
if (drbg->state != DRBG_READY) {
@@ -854,8 +855,10 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
return 0;
}
- if (drbg->fork_count != rand_fork_count) {
- drbg->fork_count = rand_fork_count;
+ fork_id = openssl_get_fork_id();
+
+ if (drbg->fork_id != fork_id) {
+ drbg->fork_id = fork_id;
reseed_required = 1;
}