summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2015-06-26 09:08:20 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2015-06-26 09:08:20 +0200
commiteea3114a5315bc6ff1ba55a37342bedebc4e6dad (patch)
tree9f9bc7f5ac90b86f38dfe0ebc30560f9f3d34416
parent6f67fbf5c8466124c594daddcb6b035f19c16518 (diff)
downloadgnutls-eea3114a5315bc6ff1ba55a37342bedebc4e6dad.tar.gz
simplified fork detection
-rw-r--r--lib/atfork.c46
-rw-r--r--lib/atfork.h56
-rw-r--r--lib/nettle/rnd-fips.c9
-rw-r--r--lib/nettle/rnd.c18
-rw-r--r--lib/pkcs11.c10
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;
}