diff options
author | Dan McDonald <danmcd@omniti.com> | 2014-06-05 00:43:20 -0400 |
---|---|---|
committer | Dan McDonald <danmcd@omniti.com> | 2014-06-06 14:58:03 -0400 |
commit | 05d57413471eaaa425913a06edc2ab33ad9b05bc (patch) | |
tree | bbef725146e3c7af7a81e951f1c3a97a5ed6a016 /usr/src/lib/libcryptoutil/common/random.c | |
parent | 06315b795c0d54f0228e0b8af497a28752dd92da (diff) | |
download | illumos-joyent-05d57413471eaaa425913a06edc2ab33ad9b05bc.tar.gz |
1667 pkcs11 may deadlock when multi-threaded consumers fork
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Saso Kiselkov <skiselkov.ml@gmail.com>
Approved by: Gordon Ross <gordon.ross@nexenta.com>
Diffstat (limited to 'usr/src/lib/libcryptoutil/common/random.c')
-rw-r--r-- | usr/src/lib/libcryptoutil/common/random.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/usr/src/lib/libcryptoutil/common/random.c b/usr/src/lib/libcryptoutil/common/random.c index 771112850a..ab07168409 100644 --- a/usr/src/lib/libcryptoutil/common/random.c +++ b/usr/src/lib/libcryptoutil/common/random.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. */ #include <stdio.h> @@ -33,6 +34,7 @@ #include <cryptoutil.h> #include <pthread.h> +#pragma init(pkcs11_random_init) static pthread_mutex_t random_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t urandom_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -181,13 +183,13 @@ pkcs11_close_common(int *fd, pthread_mutex_t *mtx) (void) pthread_mutex_unlock(mtx); } -void +static void pkcs11_close_random(void) { pkcs11_close_common(&random_fd, &random_mutex); } -void +static void pkcs11_close_urandom(void) { pkcs11_close_common(&urandom_fd, &urandom_mutex); @@ -199,7 +201,7 @@ pkcs11_close_random_seed(void) pkcs11_close_common(&random_seed_fd, &random_seed_mutex); } -void +static void pkcs11_close_urandom_seed(void) { pkcs11_close_common(&urandom_seed_fd, &urandom_seed_mutex); @@ -377,3 +379,45 @@ pkcs11_get_nzero_urandom(void *dbuf, size_t dlen) } return (0); } + +static void +pkcs11_random_prepare(void) +{ + /* + * NOTE - None of these are acquired more than one at a time. + * I can therefore acquire all four without fear of deadlock. + */ + (void) pthread_mutex_lock(&random_mutex); + (void) pthread_mutex_lock(&urandom_mutex); + (void) pthread_mutex_lock(&random_seed_mutex); + (void) pthread_mutex_lock(&urandom_seed_mutex); +} + +static void +pkcs11_random_parent_post(void) +{ + /* Drop the mutexes and get back to work! */ + (void) pthread_mutex_unlock(&urandom_seed_mutex); + (void) pthread_mutex_unlock(&random_seed_mutex); + (void) pthread_mutex_unlock(&urandom_mutex); + (void) pthread_mutex_unlock(&random_mutex); +} + +static void +pkcs11_random_child_post(void) +{ + pkcs11_random_parent_post(); + + /* Also, close the FDs, just in case. */ + pkcs11_close_random(); + pkcs11_close_urandom(); + pkcs11_close_random_seed(); + pkcs11_close_urandom_seed(); +} + +static void +pkcs11_random_init(void) +{ + (void) pthread_atfork(pkcs11_random_prepare, pkcs11_random_parent_post, + pkcs11_random_child_post); +} |