提交 2915fe19 编写于 作者: R Rich Salz

Add fork handlers, based on pthread_atfork

Only for Unix platforms
Reviewed-by: NRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3754)
上级 5ee40746
......@@ -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)
......
......@@ -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
......@@ -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
......@@ -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
......@@ -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
=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
......@@ -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
......
......@@ -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 */
......
......@@ -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:
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册