From: SiteRelEnby <125829806+SiteRelEnby@users.noreply.github.com> Date: Wed, 21 Jan 2026 02:57:52 +0000 (+0000) Subject: Fix NULL pointer dereference when zlib DSO fails to load X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=045ca33cef8d1585ecb9ee8a4ef04e6e790f6828;p=thirdparty%2Fopenssl.git Fix NULL pointer dereference when zlib DSO fails to load When ZLIB_SHARED is defined and DSO_load() fails to load the zlib library, ossl_comp_zlib_init() incorrectly returns 1 (success) while leaving all function pointers (p_compress, p_uncompress, etc.) as NULL. This causes COMP_zlib() and COMP_zlib_oneshot() to return valid-looking COMP_METHOD pointers, but when these methods are used (e.g., during TLS 1.3 certificate decompression), the NULL function pointers are dereferenced, causing a SIGSEGV crash. The bug occurs because the NULL pointer check (lines 297-303) was inside the `if (zlib_dso != NULL)` block, so it was skipped entirely when DSO_load() returned NULL. The fix moves the NULL pointer check outside the conditional block, consistent with how c_brotli.c and c_zstd.c handle this case. Now if the DSO fails to load, all function pointers remain NULL, the check catches this, and the function correctly returns 0 (failure). This also fixes an incorrect cast of p_uncompress from compress_ft to the correct uncompress_ft type. PoC demonstrating the bug: https://github.com/SiteRelEnby/openssl-zlib-poc Fixes #23563 CLA: trivial Reviewed-by: Paul Yang Reviewed-by: Paul Dale Reviewed-by: Eugene Syromiatnikov Reviewed-by: Tomas Mraz MergeDate: Thu Jan 22 17:00:50 2026 (Merged from https://github.com/openssl/openssl/pull/29699) --- diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c index 602259c821c..2fdacc3593e 100644 --- a/crypto/comp/c_zlib.c +++ b/crypto/comp/c_zlib.c @@ -284,7 +284,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) zlib_dso = DSO_load(NULL, LIBZ, NULL, 0); if (zlib_dso != NULL) { p_compress = (compress_ft)DSO_bind_func(zlib_dso, "compress"); - p_uncompress = (compress_ft)DSO_bind_func(zlib_dso, "uncompress"); + p_uncompress = (uncompress_ft)DSO_bind_func(zlib_dso, "uncompress"); p_inflateEnd = (inflateEnd_ft)DSO_bind_func(zlib_dso, "inflateEnd"); p_inflate = (inflate_ft)DSO_bind_func(zlib_dso, "inflate"); p_inflateInit_ = (inflateInit__ft)DSO_bind_func(zlib_dso, "inflateInit_"); @@ -292,14 +292,14 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) p_deflate = (deflate_ft)DSO_bind_func(zlib_dso, "deflate"); p_deflateInit_ = (deflateInit__ft)DSO_bind_func(zlib_dso, "deflateInit_"); p_zError = (zError__ft)DSO_bind_func(zlib_dso, "zError"); + } - if (p_compress == NULL || p_uncompress == NULL || p_inflateEnd == NULL - || p_inflate == NULL || p_inflateInit_ == NULL - || p_deflateEnd == NULL || p_deflate == NULL - || p_deflateInit_ == NULL || p_zError == NULL) { - ossl_comp_zlib_cleanup(); - return 0; - } + if (p_compress == NULL || p_uncompress == NULL || p_inflateEnd == NULL + || p_inflate == NULL || p_inflateInit_ == NULL + || p_deflateEnd == NULL || p_deflate == NULL + || p_deflateInit_ == NULL || p_zError == NULL) { + ossl_comp_zlib_cleanup(); + return 0; } #endif return 1;