From: Mark Andrews Date: Fri, 27 Jan 2023 05:52:59 +0000 (+1100) Subject: Handle fatal and FIPS provider interactions X-Git-Tag: v9.19.12~38^2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e029803704e21db5ad49aea8ff7de55c618b7955;p=thirdparty%2Fbind9.git Handle fatal and FIPS provider interactions When fatal is called we may be holding memory allocated by OpenSSL. This may result in the reference count for the FIPS provider not going to zero and the shared library not being unloaded during OPENSSL_cleanup. When the shared library is ultimately unloaded, when all remaining dynamically loaded libraries are freed, we have already destroyed the memory context we where using to track memory leaks / late frees resulting in INSIST being called. Disable triggering the INSIST when fatal has being called. --- diff --git a/bin/confgen/util.c b/bin/confgen/util.c index 2b0a8759b58..23b7f3fd57e 100644 --- a/bin/confgen/util.c +++ b/bin/confgen/util.c @@ -19,6 +19,8 @@ #include #include +#include + extern bool verbose; extern const char *progname; @@ -43,5 +45,6 @@ fatal(const char *format, ...) { vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); + isc__tls_setfatalmode(); exit(1); } diff --git a/bin/delv/delv.c b/bin/delv/delv.c index 110d4210d7f..a354a60e65d 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -263,6 +263,7 @@ fatal(const char *format, ...) { vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); + isc__tls_setfatalmode(); exit(1); } diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index cb846d32a95..55168fa6991 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -411,6 +411,7 @@ fatal(const char *format, ...) { vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); + isc__tls_setfatalmode(); digexit(); } diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c index 502548444cb..62c74765591 100644 --- a/bin/dnssec/dnssectool.c +++ b/bin/dnssec/dnssectool.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -82,6 +83,7 @@ fatal(const char *format, ...) { if (fatalcallback != NULL) { (*fatalcallback)(); } + isc__tls_setfatalmode(); exit(1); } diff --git a/bin/named/server.c b/bin/named/server.c index 4534cbf994a..47174867a71 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -10301,6 +10301,7 @@ fatal(const char *msg, isc_result_t result) { NAMED_LOGMODULE_SERVER, ISC_LOG_CRITICAL, "exiting (due to fatal error)"); named_os_shutdown(); + isc__tls_setfatalmode(); exit(1); } diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 9c38a6ed68c..a52dfe76e82 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -278,6 +278,7 @@ fatal(const char *format, ...) { vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); + isc__tls_setfatalmode(); exit(1); } diff --git a/bin/rndc/util.c b/bin/rndc/util.c index 2b0a8759b58..23b7f3fd57e 100644 --- a/bin/rndc/util.c +++ b/bin/rndc/util.c @@ -19,6 +19,8 @@ #include #include +#include + extern bool verbose; extern const char *progname; @@ -43,5 +45,6 @@ fatal(const char *format, ...) { vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); + isc__tls_setfatalmode(); exit(1); } diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index 61071731292..98e72ffb2ea 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -889,6 +889,7 @@ fatal(const char *format, ...) { vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); + isc__tls_setfatalmode(); exit(-2); } diff --git a/bin/tools/nsec3hash.c b/bin/tools/nsec3hash.c index d18756dabb7..aaa52d0bb04 100644 --- a/bin/tools/nsec3hash.c +++ b/bin/tools/nsec3hash.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,7 @@ fatal(const char *format, ...) { vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); + isc__tls_setfatalmode(); exit(1); } diff --git a/lib/isc/include/isc/tls.h b/lib/isc/include/isc/tls.h index 6da0361a1f4..634ba65c4e9 100644 --- a/lib/isc/include/isc/tls.h +++ b/lib/isc/include/isc/tls.h @@ -594,3 +594,6 @@ isc__tls_shutdown(void); void isc__tls_setdestroycheck(bool check); + +void +isc__tls_setfatalmode(void); diff --git a/lib/isc/tls.c b/lib/isc/tls.c index 569a041a8da..0e53775490f 100644 --- a/lib/isc/tls.c +++ b/lib/isc/tls.c @@ -77,6 +77,8 @@ isc__tls_set_thread_id(CRYPTO_THREADID *id) { } #endif +static atomic_bool handle_fatal = false; + #if !defined(LIBRESSL_VERSION_NUMBER) /* * This was crippled with LibreSSL, so just skip it: @@ -109,7 +111,9 @@ isc__tls_free_ex(void *ptr, const char *file, int line) { if (ptr == NULL) { return; } - isc__mem_free(isc__tls_mctx, ptr, 0, file, (unsigned int)line); + if (!atomic_load(&handle_fatal) || isc__tls_mctx != NULL) { + isc__mem_free(isc__tls_mctx, ptr, 0, file, (unsigned int)line); + } } #else /* ISC_MEM_TRACKLINES */ @@ -135,7 +139,9 @@ isc__tls_free_ex(void *ptr, const char *file, int line) { if (ptr == NULL) { return; } - isc__mem_free(isc__tls_mctx, ptr, 0); + if (!atomic_load(&handle_fatal) || isc__tls_mctx != NULL) { + isc__mem_free(isc__tls_mctx, ptr, 0); + } } #endif /* ISC_MEM_TRACKLINES */ @@ -1744,3 +1750,8 @@ isc_tlsctx_set_random_session_id_context(isc_tlsctx_t *ctx) { RUNTIME_CHECK( SSL_CTX_set_session_id_context(ctx, session_id_ctx, len) == 1); } + +void +isc__tls_setfatalmode(void) { + atomic_store(&handle_fatal, true); +}