From e78506c3a85b26a6659bda07705c5558ccee473b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Fri, 22 Nov 2019 11:39:57 +0100 Subject: [PATCH] Request exclusive access when crashing via fatal() When loading the configuration fails, there might be already other tasks running and calling OpenSSL library functions. The OpenSSL on_exit handler is called when exiting the main process and there's a timing race between the on_exit function that destroys OpenSSL allocated resources (threads, locks, ...) and other tasks accessing the very same resources leading to a crash in the system threading library. Therefore, the fatal() function needs to request exlusive access to the task manager to finish the already running tasks and exit only when no other tasks are running. (cherry picked from commit 952d7fde63dbe68f1a2955688ea06edf9eacc9e2) --- bin/named/server.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 4314fd1ebc..1961b22178 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -202,8 +202,8 @@ #define CHECKFATAL(op, msg) \ do { result = (op); \ - if (result != ISC_R_SUCCESS) \ - fatal(msg, result); \ + if (result != ISC_R_SUCCESS) \ + fatal(server, msg, result); \ } while (0) \ /*% @@ -432,7 +432,8 @@ const char *empty_zones[] = { }; ISC_PLATFORM_NORETURN_PRE static void -fatal(const char *msg, isc_result_t result) ISC_PLATFORM_NORETURN_POST; +fatal(named_server_t *server,const char *msg, isc_result_t result) +ISC_PLATFORM_NORETURN_POST; static void named_server_reload(isc_task_t *task, isc_event_t *event); @@ -9718,7 +9719,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) { named_server_t *server = isc_mem_get(mctx, sizeof(*server)); if (server == NULL) - fatal("allocating server object", ISC_R_NOMEMORY); + fatal(server, "allocating server object", ISC_R_NOMEMORY); server->mctx = mctx; server->task = NULL; @@ -9927,7 +9928,15 @@ named_server_destroy(named_server_t **serverp) { } static void -fatal(const char *msg, isc_result_t result) { +fatal(named_server_t *server, const char *msg, isc_result_t result) { + if (server != NULL) { + /* + * Prevent races between the OpenSSL on_exit registered + * function and any other OpenSSL calls from other tasks + * by requesting exclusive access to the task manager. + */ + (void)isc_task_beginexclusive(server->task); + } isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_CRITICAL, "%s: %s", msg, isc_result_totext(result));