From c6ea900ad5d38f8ac3b319aa4bb2a4e35f12485b Mon Sep 17 00:00:00 2001 From: ndossche Date: Thu, 21 May 2026 16:57:19 +0200 Subject: [PATCH] src: fix edge case when deflateInit2() fails with Z_VERSION_ERROR This function call can fail with `Z_VERSION_ERROR` if the compiled library vs loaded library mismatched in version number or in stream structure size. In those cases, zlib doesn't initialize the `strm_.msg` field to null. Therefore, when a `CompressionError` object is created via `ErrorForMessage()`, it can read a stale or uninitialized `strm_.msg` pointer that will cause a crash. Example ASAN report: ``` AddressSanitizer: SEGV on unknown address #0 __strlen_avx2 string/../sysdeps/x86_64/multiarch/strlen-avx2.S:76 #1 strlen (/work/node/out/Debug/node+0x1a42ab7) #2 v8::(anonymous namespace)::StringLength(char const*) /work/node/out/../deps/v8/src/api/api.cc:7581:16 #3 v8::(anonymous namespace)::StringLength(unsigned char const*) /work/node/out/../deps/v8/src/api/api.cc:7587:10 #4 v8::String::NewFromOneByte(v8::Isolate*, unsigned char const*, v8::NewStringType, int) /work/node/out/../deps/v8/src/api/api.cc:7677:3 #5 node::OneByteString(v8::Isolate*, char const*, int, v8::NewStringType) /work/node/out/../src/util-inl.h:166:10 #6 node::(anonymous namespace)::CompressionStream< node::(anonymous namespace)::ZlibContext> ::EmitError(node::(anonymous namespace) ::CompressionError const&) /work/node/out/../src/node_zlib.cc:565:7 #7 node::(anonymous namespace)::CompressionStream< node::(anonymous namespace)::ZlibContext> ::CheckError() /work/node/out/../src/node_zlib.cc:519:5 #8 node::(anonymous namespace)::CompressionStream< node::(anonymous namespace)::ZlibContext> ::AfterThreadPoolWork(int) /work/node/out/../src/node_zlib.cc:543:10 #9 node::ThreadPoolWork::ScheduleWork() ::'lambda'(uv_work_s*, int) ::operator()(uv_work_s*, int) const /work/node/out/../src/threadpoolwork-inl.h:57:15 #10 node::ThreadPoolWork::ScheduleWork() ::'lambda'(uv_work_s*, int) ::__invoke(uv_work_s*, int) /work/node/out/../src/threadpoolwork-inl.h:48:7 #11 uv__work_done /work/libuv-1.51.0/src/threadpool.c:330:5 #12 uv__async_io.part.0 /work/libuv-1.51.0/src/unix/async.c:208:5 ``` Signed-off-by: ndossche --- src/node_zlib.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/node_zlib.cc b/src/node_zlib.cc index 792d800847e105..9774c847ee50da 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -1285,6 +1285,11 @@ bool ZlibContext::InitZlib() { return false; } + // If deflateInit2() fails with Z_VERSION_ERROR, msg remains uninitialized. + // Initialize it here to avoid reading the uninitialized pointer during error + // emission. + strm_.msg = nullptr; + switch (mode_) { case DEFLATE: case GZIP: