File apache2-mod_ssl-fix-restart.patch of Package apache2.18661
---
modules/ssl/mod_ssl.c | 59 ++++++++++++++++++++++++++++++++++++++--------
modules/ssl/ssl_private.h | 7 ++++-
modules/ssl/ssl_util.c | 51 +++++++++++++++++++++++++++++++++++++--
3 files changed, 104 insertions(+), 13 deletions(-)
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -30,9 +30,12 @@
#include "util_md5.h"
#include "util_mutex.h"
#include "ap_provider.h"
+#include "http_config.h"
#include <assert.h>
+static int modssl_running_statically = 0;
+
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, pre_handshake,
(conn_rec *c,SSL *ssl,int is_proxy),
(c,ssl,is_proxy), OK, DECLINED);
@@ -297,22 +300,47 @@
/*
* the various processing hooks
*/
+static int modssl_is_prelinked(void)
+{
+ apr_size_t i = 0;
+ const module *mod;
+ while ((mod = ap_prelinked_modules[i++])) {
+ if (strcmp(mod->name, "mod_ssl.c") == 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
static apr_status_t ssl_cleanup_pre_config(void *data)
{
/*
* Try to kill the internals of the SSL library.
*/
- /* Corresponds to OPENSSL_load_builtin_modules():
- * XXX: borrowed from apps.h, but why not CONF_modules_free()
- * which also invokes CONF_modules_finish()?
- */
- CONF_modules_unload(1);
+#ifdef HAVE_FIPS
+ FIPS_mode_set(0);
+#endif
+ /* Corresponds to OBJ_create()s */
+ OBJ_cleanup();
+ /* Corresponds to OPENSSL_load_builtin_modules() */
+ CONF_modules_free();
/* Corresponds to SSL_library_init: */
EVP_cleanup();
#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
ENGINE_cleanup();
#endif
- ERR_remove_state(0);
+#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
+ SSL_COMP_free_compression_methods();
+#endif
+
+ /* Usually needed per thread, but this parent process is single-threaded */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
+ ERR_remove_thread_state(NULL);
+#else
+ ERR_remove_state(0);
+#endif
+#endif
/* Don't call ERR_free_strings in earlier versions, ERR_load_*_strings only
* actually loaded the error strings once per process due to static
@@ -321,11 +349,14 @@
ERR_free_strings();
#endif
- /* Also don't call CRYPTO_cleanup_all_ex_data here; any registered
- * ex_data indices may have been cached in static variables in
- * OpenSSL; removing them may cause havoc. Notably, with OpenSSL
+ /* Also don't call CRYPTO_cleanup_all_ex_data when linked statically here;
+ * any registered ex_data indices may have been cached in static variables
+ * in OpenSSL; removing them may cause havoc. Notably, with OpenSSL
* versions >= 0.9.8f, COMP_CTX cleanups would not be run, which
* could result in a per-connection memory leak (!). */
+ if (!modssl_running_statically) {
+ CRYPTO_cleanup_all_ex_data();
+ }
/*
* TODO: determine somewhere we can safely shove out diagnostics
@@ -339,6 +370,13 @@
apr_pool_t *plog,
apr_pool_t *ptemp)
{
+ modssl_running_statically = modssl_is_prelinked();
+
+ /* Some OpenSSL internals are allocated per-thread, make sure they
+ * are associated to the/our same thread-id until cleaned up.
+ */
+ ssl_util_thread_id_setup(pconf);
+
/* We must register the library in full, to ensure our configuration
* code can successfully test the SSL environment.
*/
@@ -357,6 +395,9 @@
"SRVName otherName form");
}
+ /* Start w/o errors (e.g. OBJ_txt2nid() above) */
+ ERR_clear_error();
+
/*
* Let us cleanup the ssl library when the module is unloaded
*/
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -882,7 +882,12 @@
char *ssl_util_readfilter(server_rec *, apr_pool_t *, const char *,
const char * const *);
BOOL ssl_util_path_check(ssl_pathcheck_t, const char *, apr_pool_t *);
-void ssl_util_thread_setup(apr_pool_t *);
+#if APR_HAS_THREADS
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+void ssl_util_thread_setup(apr_pool_t *);
+#endif
+void ssl_util_thread_id_setup(apr_pool_t *);
+#endif
int ssl_init_ssl_connection(conn_rec *c, request_rec *r);
BOOL ssl_util_vhost_matches(const char *servername, server_rec *s);
--- a/modules/ssl/ssl_util.c
+++ b/modules/ssl/ssl_util.c
@@ -247,6 +247,7 @@
}
#if APR_HAS_THREADS
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
/*
* To ensure thread-safetyness in OpenSSL - work in progress
*/
@@ -362,6 +363,33 @@
apr_pool_destroy(l->pool);
}
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+
+static void ssl_util_thr_id(CRYPTO_THREADID *id)
+{
+ /* OpenSSL needs this to return an unsigned long. On OS/390, the pthread
+ * id is a structure twice that big. Use the TCB pointer instead as a
+ * unique unsigned long.
+ */
+#ifdef __MVS__
+ struct PSA {
+ char unmapped[540]; /* PSATOLD is at offset 540 in the PSA */
+ unsigned long PSATOLD;
+ } *psaptr = 0; /* PSA is at address 0 */
+
+ CRYPTO_THREADID_set_numeric(id, psaptr->PSATOLD);
+#else
+ CRYPTO_THREADID_set_numeric(id, (unsigned long) apr_os_thread_current());
+#endif
+}
+static apr_status_t ssl_util_thr_id_cleanup(void *old)
+{
+ CRYPTO_THREADID_set_callback(old);
+ return APR_SUCCESS;
+}
+
+#else
+
static unsigned long ssl_util_thr_id(void)
{
/* OpenSSL needs this to return an unsigned long. On OS/390, the pthread
@@ -380,10 +408,17 @@
#endif
}
+static apr_status_t ssl_util_thr_id_cleanup(void *old)
+{
+ CRYPTO_set_id_callback(old);
+ return APR_SUCCESS;
+}
+
+#endif
+
static apr_status_t ssl_util_thread_cleanup(void *data)
{
CRYPTO_set_locking_callback(NULL);
- CRYPTO_set_id_callback(NULL);
CRYPTO_set_dynlock_create_callback(NULL);
CRYPTO_set_dynlock_lock_callback(NULL);
@@ -407,8 +442,6 @@
apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p);
}
- CRYPTO_set_id_callback(ssl_util_thr_id);
-
CRYPTO_set_locking_callback(ssl_util_thr_lock);
/* Set up dynamic locking scaffolding for OpenSSL to use at its
@@ -422,4 +455,16 @@
apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup,
apr_pool_cleanup_null);
}
+
+void ssl_util_thread_id_setup(apr_pool_t *p)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ CRYPTO_THREADID_set_callback(ssl_util_thr_id);
+#else
+ CRYPTO_set_id_callback(ssl_util_thr_id);
#endif
+ apr_pool_cleanup_register(p, NULL, ssl_util_thr_id_cleanup,
+ apr_pool_cleanup_null);
+}
+#endif /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
+#endif /* #if APR_HAS_THREADS */