diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-06-26 09:08:20 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-06-26 09:08:20 +0200 |
commit | eea3114a5315bc6ff1ba55a37342bedebc4e6dad (patch) | |
tree | 9f9bc7f5ac90b86f38dfe0ebc30560f9f3d34416 | |
parent | 6f67fbf5c8466124c594daddcb6b035f19c16518 (diff) | |
download | gnutls-eea3114a5315bc6ff1ba55a37342bedebc4e6dad.tar.gz |
simplified fork detection
-rw-r--r-- | lib/atfork.c | 46 | ||||
-rw-r--r-- | lib/atfork.h | 56 | ||||
-rw-r--r-- | lib/nettle/rnd-fips.c | 9 | ||||
-rw-r--r-- | lib/nettle/rnd.c | 18 | ||||
-rw-r--r-- | lib/pkcs11.c | 10 |
5 files changed, 61 insertions, 78 deletions
diff --git a/lib/atfork.c b/lib/atfork.c index dec8d2cb2c..793de391cf 100644 --- a/lib/atfork.c +++ b/lib/atfork.c @@ -31,44 +31,17 @@ #include <sys/types.h> #include <atfork.h> -#ifndef _WIN32 - -# if defined(HAVE___REGISTER_ATFORK) || defined(HAVE_PTHREAD_ATFORK) -# define HAVE_ATFORK -# endif +unsigned int gnutls_forkid = 0; -/* The maximum number of users of the API */ -# define MAX_VALS 6 - -static unsigned int * fvals[MAX_VALS]; -static unsigned int fvals_size = 0; +#ifndef _WIN32 # ifdef HAVE_ATFORK static void fork_handler(void) { - unsigned i; - for (i=0;i<fvals_size;i++) - *fvals[i] = 1; + gnutls_forkid++; } # endif -static void set_val_on_fork(unsigned int *val, unsigned int def) -{ - if (fvals_size >= MAX_VALS) - abort(); /* internal error */ - *val = def; - fvals[fvals_size++] = val; -} - -void _gnutls_fork_set_val(unsigned int *val) -{ -# ifdef HAVE_ATFORK - set_val_on_fork(val, 0); -# else - set_val_on_fork(val, getpid()); -# endif -} - # if defined(HAVE_PTHREAD_ATFORK) # include <pthread.h> @@ -93,9 +66,22 @@ int _gnutls_register_fork_handler(void) # else +unsigned int _gnutls_get_forkid(void) +{ + return getpid(); +} + +int _gnutls_detect_fork(unsigned int forkid) +{ + if (getpid() == forkid) + return 0; + return 1; +} + /* we have to detect fork manually */ int _gnutls_register_fork_handler(void) { + gnutls_forkid = getpid(); return 0; } diff --git a/lib/atfork.h b/lib/atfork.h index dfb682bd90..c8768877ff 100644 --- a/lib/atfork.h +++ b/lib/atfork.h @@ -21,56 +21,44 @@ */ #ifndef ATFORK_H -#define ATFORK_H +# define ATFORK_H #include <config.h> #include <gnutls_int.h> +extern unsigned int gnutls_forkid; + +#if defined(HAVE___REGISTER_ATFORK) || defined(HAVE_PTHREAD_ATFORK) +# define HAVE_ATFORK +#endif + #ifndef _WIN32 /* API */ int _gnutls_register_fork_handler(void); /* global init */ -/* Each user of the API that needs to be notified registers - * a pointer to an int */ -void _gnutls_fork_set_val(unsigned int *val); - -/* - * Each user, calls this function with the integer registered - * to check whether a fork is detected - * - * unsigned _gnutls_fork_detected(unsigned int *v); - */ - -# if defined(HAVE___REGISTER_ATFORK) || defined(HAVE_PTHREAD_ATFORK) -inline static -unsigned _gnutls_fork_detected(unsigned int *v) +# if defined(HAVE_ATFORK) +inline static int _gnutls_detect_fork(unsigned int forkid) { - if (*v != 0) { - *v = 0; - return 1; - } - return 0; + if (forkid == gnutls_forkid) + return 0; + return 1; } -# else -# include <unistd.h> -inline static -unsigned _gnutls_fork_detected(unsigned int *v) +inline static unsigned int _gnutls_get_forkid(void) { - if (getpid() != (pid_t)*v) { - *v = getpid(); - return 1; - } - return 0; + return gnutls_forkid; } - +# else +int _gnutls_detect_fork(unsigned int forkid); +unsigned int _gnutls_get_forkid(void); # endif -#else /* _WIN32 */ -# define _gnutls_fork_set_val(x) 0 -# define _gnutls_register_fork_handler() 0 -# define _gnutls_fork_detected(x) 0 +#else + +# define _gnutls_detect_fork(x) 0 +# define _gnutls_get_forkid() 0 + #endif #endif diff --git a/lib/nettle/rnd-fips.c b/lib/nettle/rnd-fips.c index 33c23e678c..8e31f73895 100644 --- a/lib/nettle/rnd-fips.c +++ b/lib/nettle/rnd-fips.c @@ -48,7 +48,7 @@ struct fips_ctx { struct drbg_aes_ctx nonce_context; struct drbg_aes_ctx normal_context; struct drbg_aes_ctx strong_context; - unsigned int dfork; + unsigned int forkid; }; static int _rngfips_ctx_reinit(struct fips_ctx *fctx); @@ -60,7 +60,7 @@ static int get_random(struct drbg_aes_ctx *ctx, struct fips_ctx *fctx, { int ret; - if ( _gnutls_fork_detected(&fctx->dfork) != 0) { + if ( _gnutls_detect_fork(fctx->forkid) != 0) { ret = _rngfips_ctx_reinit(fctx); if (ret < 0) return gnutls_assert_val(ret); @@ -135,7 +135,8 @@ static int _rngfips_ctx_init(struct fips_ctx *fctx) if (ret < 0) return gnutls_assert_val(ret); - _gnutls_fork_set_val(&fctx->dfork); + fctx->forkid = _gnutls_get_forkid(); + return 0; } @@ -158,6 +159,8 @@ static int _rngfips_ctx_reinit(struct fips_ctx *fctx) if (ret < 0) return gnutls_assert_val(ret); + fctx->forkid = _gnutls_get_forkid(); + return 0; } diff --git a/lib/nettle/rnd.c b/lib/nettle/rnd.c index d4dbdc144f..8ac30a8d95 100644 --- a/lib/nettle/rnd.c +++ b/lib/nettle/rnd.c @@ -54,7 +54,7 @@ struct nonce_ctx_st { struct salsa20_ctx ctx; unsigned int counter; void *mutex; - unsigned int dfork; + unsigned int forkid; }; struct rnd_ctx_st { @@ -64,7 +64,7 @@ struct rnd_ctx_st { time_t trivia_previous_time; time_t trivia_time_count; void *mutex; - unsigned dfork; /* detect fork() */ + unsigned forkid; }; static struct rnd_ctx_st rnd_ctx; @@ -178,7 +178,7 @@ static int nonce_rng_init(struct nonce_ctx_st *ctx, * from the old key */ salsa20r12_crypt(&ctx->ctx, nonce_key_size, nonce_key, nonce_key); } else { - _gnutls_fork_set_val(&ctx->dfork); + ctx->forkid = _gnutls_get_forkid(); /* when initializing read the IV from the system randomness source */ ret = _rnd_get_system_entropy(iv, sizeof(iv)); @@ -229,7 +229,7 @@ static int wrap_nettle_rnd_init(void **ctx) _rnd_get_event(&event); - _gnutls_fork_set_val(&rnd_ctx.dfork); + rnd_ctx.forkid = _gnutls_get_forkid(); ret = do_device_source(&rnd_ctx, 1, &event); if (ret < 0) { @@ -278,7 +278,7 @@ wrap_nettle_rnd_nonce(void *_ctx, void *data, size_t datasize) RND_LOCK(&nonce_ctx); - if (_gnutls_fork_detected(&nonce_ctx.dfork)) { + if (_gnutls_detect_fork(nonce_ctx.forkid)) { reseed = 1; } @@ -295,6 +295,8 @@ wrap_nettle_rnd_nonce(void *_ctx, void *data, size_t datasize) gnutls_assert(); goto cleanup; } + + nonce_ctx.forkid = _gnutls_get_forkid(); } salsa20r12_crypt(&nonce_ctx.ctx, datasize, data, data); @@ -322,7 +324,7 @@ wrap_nettle_rnd(void *_ctx, int level, void *data, size_t datasize) RND_LOCK(&rnd_ctx); - if (_gnutls_fork_detected(&rnd_ctx.dfork)) { /* fork() detected */ + if (_gnutls_detect_fork(rnd_ctx.forkid)) { /* fork() detected */ memset(&rnd_ctx.device_last_read, 0, sizeof(rnd_ctx.device_last_read)); reseed = 1; } @@ -340,8 +342,10 @@ wrap_nettle_rnd(void *_ctx, int level, void *data, size_t datasize) goto cleanup; } - if (reseed != 0) + if (reseed != 0) { yarrow256_slow_reseed(&rnd_ctx.yctx); + rnd_ctx.forkid = _gnutls_get_forkid(); + } yarrow256_random(&rnd_ctx.yctx, datasize, data); ret = 0; diff --git a/lib/pkcs11.c b/lib/pkcs11.c index dadfd57fff..cf361dfd31 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -100,7 +100,7 @@ struct find_cert_st { static struct gnutls_pkcs11_provider_st providers[MAX_PROVIDERS]; static unsigned int active_providers = 0; static unsigned int providers_initialized = 0; -static unsigned int dfork = 0; +static unsigned int pkcs11_forkid = 0; gnutls_pkcs11_token_callback_t _gnutls_token_func; void *_gnutls_token_data; @@ -256,7 +256,7 @@ int _gnutls_pkcs11_check_init(void) if (providers_initialized != 0) { ret = 0; - if (_gnutls_fork_detected(&dfork)) { + if (_gnutls_detect_fork(pkcs11_forkid)) { /* if we are initialized but a fork is detected */ ret = gnutls_pkcs11_reinit(); if (ret == 0) @@ -761,7 +761,7 @@ gnutls_pkcs11_init(unsigned int flags, const char *deprecated_config_file) } init++; - _gnutls_fork_set_val(&dfork); + pkcs11_forkid = _gnutls_get_forkid(); p11_kit_pin_register_callback(P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback, NULL, @@ -807,7 +807,7 @@ int gnutls_pkcs11_reinit(void) ck_rv_t rv; /* make sure that we don't call more than once after a fork */ - if (_gnutls_fork_detected(&dfork) == 0) + if (_gnutls_detect_fork(pkcs11_forkid) == 0) return 0; for (i = 0; i < active_providers; i++) { @@ -826,6 +826,8 @@ int gnutls_pkcs11_reinit(void) } } + pkcs11_forkid = _gnutls_get_forkid(); + return 0; } |