Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Henry <luhenry@microsoft.com>2017-11-13 23:16:03 +0300
committerGitHub <noreply@github.com>2017-11-13 23:16:03 +0300
commit33eb71ae07d40eb968fe15c7eec5db3950c466b3 (patch)
tree83b4df7a62a0a09bd3f4c8b8105c8d7eb9cafb44 /mcs/class/System
parentbf1b5dced0ffe257fc208e499f9c524afcc469b2 (diff)
[System] Fix DeflateStream crash with high concurrency on Read/Write/Close (#5994)
Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=56727
Diffstat (limited to 'mcs/class/System')
-rw-r--r--mcs/class/System/System.IO.Compression/DeflateStream.cs42
1 files changed, 28 insertions, 14 deletions
diff --git a/mcs/class/System/System.IO.Compression/DeflateStream.cs b/mcs/class/System/System.IO.Compression/DeflateStream.cs
index 354a16e39e3..64f20595975 100644
--- a/mcs/class/System/System.IO.Compression/DeflateStream.cs
+++ b/mcs/class/System/System.IO.Compression/DeflateStream.cs
@@ -332,7 +332,7 @@ namespace System.IO.Compression
UnmanagedReadOrWrite feeder; // This will be passed to unmanaged code and used there
Stream base_stream;
- IntPtr z_stream;
+ SafeDeflateStreamHandle z_stream;
GCHandle data;
bool disposed;
byte [] io_buffer;
@@ -347,7 +347,7 @@ namespace System.IO.Compression
dsn.data = GCHandle.Alloc (dsn);
dsn.feeder = mode == CompressionMode.Compress ? new UnmanagedReadOrWrite (UnmanagedWrite) : new UnmanagedReadOrWrite (UnmanagedRead);
dsn.z_stream = CreateZStream (mode, gzip, dsn.feeder, GCHandle.ToIntPtr (dsn.data));
- if (dsn.z_stream == IntPtr.Zero) {
+ if (dsn.z_stream.IsInvalid) {
dsn.Dispose (true);
return null;
}
@@ -369,10 +369,7 @@ namespace System.IO.Compression
io_buffer = null;
- IntPtr zz = z_stream;
- z_stream = IntPtr.Zero;
- if (zz != IntPtr.Zero)
- CloseZStream (zz); // This will Flush() the remaining output if any
+ z_stream.Dispose();
}
if (data.IsAllocated) {
@@ -498,21 +495,21 @@ namespace System.IO.Compression
#if !ORBIS
[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
- static extern IntPtr CreateZStream (CompressionMode compress, bool gzip, UnmanagedReadOrWrite feeder, IntPtr data);
+ static extern SafeDeflateStreamHandle CreateZStream (CompressionMode compress, bool gzip, UnmanagedReadOrWrite feeder, IntPtr data);
[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
static extern int CloseZStream (IntPtr stream);
[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
- static extern int Flush (IntPtr stream);
+ static extern int Flush (SafeDeflateStreamHandle stream);
[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
- static extern int ReadZStream (IntPtr stream, IntPtr buffer, int length);
+ static extern int ReadZStream (SafeDeflateStreamHandle stream, IntPtr buffer, int length);
[DllImport (LIBNAME, CallingConvention=CallingConvention.Cdecl)]
- static extern int WriteZStream (IntPtr stream, IntPtr buffer, int length);
+ static extern int WriteZStream (SafeDeflateStreamHandle stream, IntPtr buffer, int length);
#else
- static IntPtr CreateZStream (CompressionMode compress, bool gzip, UnmanagedReadOrWrite feeder, IntPtr data)
+ static SafeDeflateStreamHandle CreateZStream (CompressionMode compress, bool gzip, UnmanagedReadOrWrite feeder, IntPtr data)
{
throw new PlatformNotSupportedException ();
}
@@ -522,22 +519,39 @@ namespace System.IO.Compression
throw new PlatformNotSupportedException ();
}
- static int Flush (IntPtr stream)
+ static int Flush (SafeDeflateStreamHandle stream)
{
throw new PlatformNotSupportedException ();
}
- static int ReadZStream (IntPtr stream, IntPtr buffer, int length)
+ static int ReadZStream (SafeDeflateStreamHandle stream, IntPtr buffer, int length)
{
throw new PlatformNotSupportedException ();
}
- static int WriteZStream (IntPtr stream, IntPtr buffer, int length)
+ static int WriteZStream (SafeDeflateStreamHandle stream, IntPtr buffer, int length)
{
throw new PlatformNotSupportedException ();
}
#endif
+ sealed class SafeDeflateStreamHandle : SafeHandle
+ {
+ public override bool IsInvalid
+ {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ private SafeDeflateStreamHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ override protected bool ReleaseHandle()
+ {
+ DeflateStreamNative.CloseZStream(handle);
+ return true;
+ }
+ }
}
}