Skip to content

Commit b6de702

Browse files
committed
mod_ssl: Use OPENSSL_INIT_NO_ATEXIT when available.
1 parent 0ba38c2 commit b6de702

File tree

1 file changed

+39
-24
lines changed

1 file changed

+39
-24
lines changed

modules/ssl/mod_ssl.c

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,7 @@
4040
int 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. */
5245
static 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
332325
static 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() */
346339
static 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

398406
static 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

Comments
 (0)