#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>
# 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;
}
*/
#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
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);
{
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);
if (ret < 0)
return gnutls_assert_val(ret);
- _gnutls_fork_set_val(&fctx->dfork);
+ fctx->forkid = _gnutls_get_forkid();
+
return 0;
}
if (ret < 0)
return gnutls_assert_val(ret);
+ fctx->forkid = _gnutls_get_forkid();
+
return 0;
}
struct salsa20_ctx ctx;
unsigned int counter;
void *mutex;
- unsigned int dfork;
+ unsigned int forkid;
};
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;
* 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));
_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) {
RND_LOCK(&nonce_ctx);
- if (_gnutls_fork_detected(&nonce_ctx.dfork)) {
+ if (_gnutls_detect_fork(nonce_ctx.forkid)) {
reseed = 1;
}
gnutls_assert();
goto cleanup;
}
+
+ nonce_ctx.forkid = _gnutls_get_forkid();
}
salsa20r12_crypt(&nonce_ctx.ctx, datasize, data, data);
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;
}
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;
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;
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)
}
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,
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++) {
}
}
+ pkcs11_forkid = _gnutls_get_forkid();
+
return 0;
}