4040int ssl_running_on_valgrind = 0 ;
4141#endif
4242
43- #if HAVE_OPENSSL_INIT_SSL || (OPENSSL_VERSION_NUMBER >= 0x10100000L && \
44- !defined(LIBRESSL_VERSION_NUMBER ))
45- /* Openssl v1.1+ handles all termination automatically from
46- * OPENSSL_init_ssl(). No manual initialization is required. */
47- #else
48- /* For older OpenSSL releases, "manual" initialization and cleanup are
49- * required. */
50- #define NEED_MANUAL_OPENSSL_INIT
43+ #if !HAVE_OPENSSL_INIT_SSL
5144/* Will be set to true if mod_ssl is built statically into httpd. */
5245static int modssl_running_statically = 0 ;
5346#endif
@@ -328,7 +321,7 @@ static const command_rec ssl_config_cmds[] = {
328321 AP_END_CMD
329322};
330323
331- #ifdef NEED_MANUAL_OPENSSL_INIT
324+ #if ! HAVE_OPENSSL_INIT_SSL
332325static int modssl_is_prelinked (void )
333326{
334327 apr_size_t i = 0 ;
@@ -340,11 +333,25 @@ static int modssl_is_prelinked(void)
340333 }
341334 return 0 ;
342335}
336+ #endif /* !HAVE_OPENSSL_INIT_SSL */
343337
344- /* Termination below is for legacy Openssl versions v1.0.x and
345- * older. */
338+ /* Cleanup what's done in ssl_hook_pre_config() */
346339static apr_status_t ssl_cleanup_pre_config (void * data )
347340{
341+ #if HAVE_OPENSSL_INIT_SSL
342+ /* Let's call OPENSSL_cleanup() on exit only when using OPENSSL_INIT_NO_ATEXIT,
343+ * not on restart/reload or the next OPENSSL_init_ssl() in pre_config would not
344+ * (re)initialize anything.
345+ */
346+ #ifdef OPENSSL_INIT_NO_ATEXIT
347+ if (ap_state_query (AP_SQ_MAIN_STATE ) == AP_SQ_MS_EXITING )
348+ OPENSSL_cleanup ();
349+ #endif
350+
351+ #else /* HAVE_OPENSSL_INIT_SSL */
352+ /* Termination below is for legacy Openssl versions v1.0.x and
353+ * older. */
354+
348355 /* Corresponds to OBJ_create()s */
349356 OBJ_cleanup ();
350357 /* Corresponds to OPENSSL_load_builtin_modules() */
@@ -367,7 +374,7 @@ static apr_status_t ssl_cleanup_pre_config(void *data)
367374#else
368375 ERR_remove_state (0 );
369376#endif
370- #endif
377+ #endif /* HAVE_OPENSSL_INIT_SSL */
371378
372379 /* Don't call ERR_free_strings in earlier versions, ERR_load_*_strings only
373380 * actually loaded the error strings once per process due to static
@@ -391,9 +398,10 @@ static apr_status_t ssl_cleanup_pre_config(void *data)
391398 * CRYPTO_mem_leaks_fp(stderr);
392399 */
393400
401+ #endif /* HAVE_OPENSSL_INIT_SSL */
402+
394403 return APR_SUCCESS ;
395404}
396- #endif /* NEED_MANUAL_OPENSSL_INIT */
397405
398406static int ssl_hook_pre_config (apr_pool_t * pconf ,
399407 apr_pool_t * plog ,
@@ -403,17 +411,26 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
403411 ssl_running_on_valgrind = RUNNING_ON_VALGRIND ;
404412#endif
405413
406- #ifndef NEED_MANUAL_OPENSSL_INIT
407- /* Openssl v1.1+ handles all initialisation automatically, apart
408- * from hints as to how we want to use the library.
414+ #if HAVE_OPENSSL_INIT_SSL
415+ /* Openssl v1.1+ handles all initialisation and termination automatically,
416+ * apart from hints as to how we want to use the library. We tell openssl
417+ * we want to include engine support.
409418 *
410- * We tell openssl we want to include engine support.
419+ * Openssl v3.0+ allows to disable builtin atexit() handler for termination
420+ * by using OPENSSL_INIT_NO_ATEXIT, which we use because atexit() handlers
421+ * are inherited by children processes and can cause issues/crashes when
422+ * run multiple times. This allows to call OPENSSL_cleanup() manually from
423+ * ssl_cleanup_pre_config() when (and only when) httpd is exiting.
411424 */
412- OPENSSL_init_ssl (OPENSSL_INIT_ENGINE_ALL_BUILTIN , NULL );
425+ OPENSSL_init_ssl (OPENSSL_INIT_ENGINE_ALL_BUILTIN
426+ #ifdef OPENSSL_INIT_NO_ATEXIT
427+ | OPENSSL_INIT_NO_ATEXIT
428+ #endif
429+ , NULL );
413430
414- #else
431+ #else /* HAVE_OPENSSL_INIT_SSL */
415432 /* Configuration below is for legacy versions Openssl v1.0 and
416- * older.
433+ * older, "manual" initialization and cleanup are required .
417434 */
418435 modssl_running_statically = modssl_is_prelinked ();
419436
@@ -433,7 +450,7 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
433450#endif
434451 OpenSSL_add_all_algorithms ();
435452 OPENSSL_load_builtin_modules ();
436- #endif /* NEED_MANUAL_OPENSSL_INIT */
453+ #endif /* HAVE_OPENSSL_INIT_SSL */
437454
438455 if (OBJ_txt2nid ("id-on-dnsSRV" ) == NID_undef ) {
439456 (void )OBJ_create ("1.3.6.1.5.5.7.8.7" , "id-on-dnsSRV" ,
@@ -444,13 +461,11 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
444461 ERR_clear_error ();
445462
446463
447- #ifdef NEED_MANUAL_OPENSSL_INIT
448464 /*
449465 * Let us cleanup the ssl library when the module is unloaded
450466 */
451467 apr_pool_cleanup_register (pconf , NULL , ssl_cleanup_pre_config ,
452- apr_pool_cleanup_null );
453- #endif
468+ apr_pool_cleanup_null );
454469
455470 /* Register to handle mod_status status page generation */
456471 ssl_scache_status_register (pconf );
0 commit comments