Add fork handlers, based on pthread_atfork

Only for Unix platforms

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3754)
This commit is contained in:
Rich Salz 2017-06-22 14:00:06 -04:00
parent 5ee407460b
commit 2915fe19a6
9 changed files with 123 additions and 1 deletions

View File

@ -66,6 +66,7 @@ extern unsigned int OPENSSL_ia32cap_P[];
void OPENSSL_showfatal(const char *fmta, ...);
extern int OPENSSL_NONPIC_relocated;
void crypto_cleanup_all_ex_data_int(void);
int openssl_init_fork_handlers(void);
int openssl_strerror_r(int errnum, char *buf, size_t buflen);
# if !defined(OPENSSL_NO_STDIO)

View File

@ -552,6 +552,10 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
&& !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
return 0;
if ((opts & OPENSSL_INIT_NO_ATFORK) == 0
&& !openssl_init_fork_handlers())
return 0;
if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
&& !RUN_ONCE(&config, ossl_init_no_config))
return 0;
@ -677,3 +681,28 @@ int OPENSSL_atexit(void (*handler)(void))
return 1;
}
#ifdef OPENSSL_SYS_UNIX
/*
* The following three functions are for OpenSSL developers. This is
* where we set/reset state across fork (called via pthread_atfork when
* it exists, or manually by the application when it doesn't).
*
* WARNING! If you put code in either OPENSSL_fork_parent or
* OPENSSL_fork_child, you MUST MAKE SURE that they are async-signal-
* safe. See this link, for example:
* http://man7.org/linux/man-pages/man7/signal-safety.7.html
*/
void OPENSSL_fork_prepare(void)
{
}
void OPENSSL_fork_parent(void)
{
}
void OPENSSL_fork_child(void)
{
}
#endif

View File

@ -121,4 +121,9 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
return 1;
}
int openssl_init_fork_handlers(void)
{
return 0;
}
#endif

View File

@ -8,6 +8,7 @@
*/
#include <openssl/crypto.h>
#include <internal/cryptlib.h>
#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS)
@ -168,4 +169,13 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
return 1;
}
int openssl_init_fork_handlers(void)
{
# ifdef OPENSSL_SYS_UNIX
if (pthread_atfork(OPENSSL_fork_prepare,
OPENSSL_fork_parent, OPENSSL_fork_child) == 0)
return 1;
# endif
return 0;
}
#endif

View File

@ -133,4 +133,9 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
return 1;
}
int openssl_init_fork_handlers(void)
{
return 0;
}
#endif

View File

@ -0,0 +1,58 @@
=pod
=head1 NAME
OPENSSL_fork_prepare,
OPENSSL_fork_parent,
OPENSSL_fork_child
- OpenSSL fork handlers
=head1 SYNOPSIS
#include <openssl/crypto.h>
void OPENSSL_fork_prepare(void);
void OPENSSL_fork_parent(void);
void OPENSSL_fork_child(void);
=head1 DESCRIPTION
OpenSSL has state that should be reset when a process forks. For example,
the entropy pool used to generate random numbers (and therefore encryption
keys) should not be shared across multiple programs.
The OPENSSL_fork_prepare(), OPENSSL_fork_parent(), and OPENSSL_fork_child()
functions are used to reset this internal state.
Platforms without fork(2) will probably not need to use these functions.
Platforms with fork(2) but without pthreads_atfork(3) will probably need
to call them manually, as described in the following paragraph. Platforms
such as Linux that have both functions will normally not need to call these
functions as the OpenSSL library will do so automatically.
L<OPENSSL_init_crypto(3)> will register these funtions with the appropriate
hander, unless the B<OPENSSL_INIT_NO_ATFORK> flag is used. For those
applications, these functions can be called directly. They should be used
according to the calling sequence described by the pthreads_atfork(3)
documentation, which is summarized here. OPENSSL_fork_prepare() should
be called before a fork() is done. After the fork() returns, the parent
process should call OPENSSL_fork_parent() and the child process should
call OPENSSL_fork_child().
=head1 SEE ALSO
L<OPENSSL_init_crypto(3)>
=head1 HISTORY
These functions were added in OpenSSL 1.1.1.
=head1 COPYRIGHT
Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -150,6 +150,11 @@ With this option the library will automatically load and initialise all the
built in engines listed above with the exception of the openssl and dasync
engines. This not a default option.
=item OPENSSL_INIT_NO_ATFORK
With this option the library will not register its fork handlers.
See OPENSSL_fork_prepare(3) for details.
=back
Multiple options may be combined together in a single call to

View File

@ -332,6 +332,11 @@ int FIPS_mode(void);
int FIPS_mode_set(int r);
void OPENSSL_init(void);
# ifdef OPENSSL_SYS_UNIX
void OPENSSL_fork_prepare(void);
void OPENSSL_fork_parent(void);
void OPENSSL_fork_child(void);
# endif
struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
@ -364,7 +369,8 @@ int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len);
# define OPENSSL_INIT_ENGINE_CAPI 0x00002000L
# define OPENSSL_INIT_ENGINE_PADLOCK 0x00004000L
# define OPENSSL_INIT_ENGINE_AFALG 0x00008000L
/* OPENSSL_INIT flag 0x00010000 reserved for internal use */
# define OPENSSL_INIT_reserved_internal 0x00010000L
# define OPENSSL_INIT_NO_ATFORK 0x00020000L
/* OPENSSL_INIT flag range 0xfff00000 reserved for OPENSSL_init_ssl() */
/* Max OPENSSL_INIT flag value is 0x80000000 */

View File

@ -4342,3 +4342,6 @@ OSSL_STORE_INFO_set0_NAME_description 4284 1_1_1 EXIST::FUNCTION:
OSSL_STORE_INFO_get1_NAME_description 4285 1_1_1 EXIST::FUNCTION:
OSSL_STORE_do_all_loaders 4286 1_1_1 EXIST::FUNCTION:
OSSL_STORE_LOADER_get0_engine 4287 1_1_1 EXIST::FUNCTION:
OPENSSL_fork_prepare 4288 1_1_1 EXIST:UNIX:FUNCTION:
OPENSSL_fork_parent 4289 1_1_1 EXIST:UNIX:FUNCTION:
OPENSSL_fork_child 4290 1_1_1 EXIST:UNIX:FUNCTION: