From efaefb52f4bc7d27035c5a2091a16de8ed3e07dc Mon Sep 17 00:00:00 2001
From: Radek Zikmund <r.zikmund.rz@gmail.com>
Date: Fri, 29 May 2026 12:37:35 +0200
Subject: [PATCH 1/3] Fix race between zlib Inflate/Deflate and Dispose

Hold a SafeHandle ref via DangerousAddRef/Release around the native Inflate, InflateReset2_, and Deflate calls so a concurrent Dispose cannot run InflateEnd/DeflateEnd and free the zlib state from underneath an in-flight operation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 .../src/System/IO/Compression/ZLibNative.cs   | 57 +++++++++++++++----
 1 file changed, 45 insertions(+), 12 deletions(-)

diff --git a/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs b/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
index 0a934dbd6e55cb..1cbe6cdc9c03f8 100644
--- a/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
+++ b/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
@@ -348,12 +348,23 @@ private unsafe void DeflateInit2_(CompressionLevel level, int windowBits, int me
 
             public unsafe ErrorCode Deflate(FlushCode flush)
             {
-                EnsureNotDisposed();
-                EnsureState(State.InitializedForDeflate);
+                bool refAdded = false;
+                try
+                {
+                    DangerousAddRef(ref refAdded);
+                    EnsureState(State.InitializedForDeflate);
 
-                fixed (ZStream* stream = &_zStream)
+                    fixed (ZStream* stream = &_zStream)
+                    {
+                        return Interop.ZLib.Deflate(stream, flush);
+                    }
+                }
+                finally
                 {
-                    return Interop.ZLib.Deflate(stream, flush);
+                    if (refAdded)
+                    {
+                        DangerousRelease();
+                    }
                 }
             }
 
@@ -395,23 +406,45 @@ private unsafe void InflateInit2_(int windowBits)
 
             public unsafe ErrorCode InflateReset2_(int windowBits)
             {
-                EnsureNotDisposed();
-                EnsureState(State.InitializedForInflate);
+                bool refAdded = false;
+                try
+                {
+                    DangerousAddRef(ref refAdded);
+                    EnsureState(State.InitializedForInflate);
 
-                fixed (ZStream* stream = &_zStream)
+                    fixed (ZStream* stream = &_zStream)
+                    {
+                        return Interop.ZLib.InflateReset2_(stream, windowBits);
+                    }
+                }
+                finally
                 {
-                    return Interop.ZLib.InflateReset2_(stream, windowBits);
+                    if (refAdded)
+                    {
+                        DangerousRelease();
+                    }
                 }
             }
 
             public unsafe ErrorCode Inflate(FlushCode flush)
             {
-                EnsureNotDisposed();
-                EnsureState(State.InitializedForInflate);
+                bool refAdded = false;
+                try
+                {
+                    DangerousAddRef(ref refAdded);
+                    EnsureState(State.InitializedForInflate);
 
-                fixed (ZStream* stream = &_zStream)
+                    fixed (ZStream* stream = &_zStream)
+                    {
+                        return Interop.ZLib.Inflate(stream, flush);
+                    }
+                }
+                finally
                 {
-                    return Interop.ZLib.Inflate(stream, flush);
+                    if (refAdded)
+                    {
+                        DangerousRelease();
+                    }
                 }
             }
 

From a15ff168b19619531df0ed04cdca7cca5ddeaac6 Mon Sep 17 00:00:00 2001
From: Radek Zikmund <r.zikmund.rz@gmail.com>
Date: Fri, 29 May 2026 13:18:10 +0200
Subject: [PATCH 2/3] Remove unused EnsureNotDisposed helper

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 .../Common/src/System/IO/Compression/ZLibNative.cs         | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs b/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
index 1cbe6cdc9c03f8..807c19fe37fd20 100644
--- a/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
+++ b/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
@@ -288,11 +288,6 @@ public uint AvailOut
                 set { _zStream.availOut = value; }
             }
 
-            private void EnsureNotDisposed()
-            {
-                ObjectDisposedException.ThrowIf(InitializationState == State.Disposed, this);
-            }
-
             private void EnsureState(State requiredState)
             {
                 if (InitializationState != requiredState)
@@ -370,7 +365,6 @@ public unsafe ErrorCode Deflate(FlushCode flush)
 
             public unsafe ErrorCode DeflateEnd()
             {
-                EnsureNotDisposed();
                 EnsureState(State.InitializedForDeflate);
 
                 fixed (ZStream* stream = &_zStream)
@@ -450,7 +444,6 @@ public unsafe ErrorCode Inflate(FlushCode flush)
 
             public unsafe ErrorCode InflateEnd()
             {
-                EnsureNotDisposed();
                 EnsureState(State.InitializedForInflate);
 
                 fixed (ZStream* stream = &_zStream)

From 74af2a0c49040393811737f9bbc956009829db04 Mon Sep 17 00:00:00 2001
From: Radek Zikmund <r.zikmund.rz@gmail.com>
Date: Mon, 1 Jun 2026 09:39:56 +0200
Subject: [PATCH 3/3] Make DeflateEnd/InflateEnd private

---
 src/libraries/Common/src/System/IO/Compression/ZLibNative.cs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs b/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
index 807c19fe37fd20..76de2405c2d388 100644
--- a/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
+++ b/src/libraries/Common/src/System/IO/Compression/ZLibNative.cs
@@ -363,7 +363,7 @@ public unsafe ErrorCode Deflate(FlushCode flush)
                 }
             }
 
-            public unsafe ErrorCode DeflateEnd()
+            private unsafe ErrorCode DeflateEnd()
             {
                 EnsureState(State.InitializedForDeflate);
 
@@ -442,7 +442,7 @@ public unsafe ErrorCode Inflate(FlushCode flush)
                 }
             }
 
-            public unsafe ErrorCode InflateEnd()
+            private unsafe ErrorCode InflateEnd()
             {
                 EnsureState(State.InitializedForInflate);
 
