[System]: Fix memory leak in AppleTls. (#5305)
authorMartin Baulig <mabaul@microsoft.com>
Wed, 9 Aug 2017 16:27:28 +0000 (12:27 -0400)
committerGitHub <noreply@github.com>
Wed, 9 Aug 2017 16:27:28 +0000 (12:27 -0400)
* [System]: Fix memory leak in AppleTls.

* Apply Miguel's patch to use GCHandleType.Weak.

* Actually assign context.

mcs/class/System/Mono.AppleTls/AppleTlsContext.cs

index 4fa1730df2a10ffc33fc7d9a5a792259737b8db6..563e35f01d15e9f6583699ec2273c4a641919b82 100644 (file)
@@ -44,7 +44,7 @@ namespace Mono.AppleTls
 
                GCHandle handle;
                IntPtr context;
-               IntPtr connectionId;
+
                SslReadFunc readFunc;
                SslWriteFunc writeFunc;
 
@@ -73,8 +73,7 @@ namespace Mono.AppleTls
                        : base (parent, serverMode, targetHost, enabledProtocols,
                                serverCertificate, clientCertificates, askForClientCert)
                {
-                       handle = GCHandle.Alloc (this);
-                       connectionId = GCHandle.ToIntPtr (handle);
+                       handle = GCHandle.Alloc (this, GCHandleType.Weak);
                        readFunc = NativeReadCallback;
                        writeFunc = NativeWriteCallback;
 
@@ -274,7 +273,7 @@ namespace Mono.AppleTls
                        var result = SSLSetIOFuncs (Handle, readFunc, writeFunc);
                        CheckStatusAndThrow (result);
 
-                       result = SSLSetConnection (Handle, connectionId);
+                       result = SSLSetConnection (Handle, GCHandle.ToIntPtr (handle));
                        CheckStatusAndThrow (result);
 
                        if ((EnabledProtocols & SSA.SslProtocols.Tls) != 0)
@@ -684,18 +683,19 @@ namespace Mono.AppleTls
                [Mono.Util.MonoPInvokeCallback (typeof (SslReadFunc))]
                static SslStatus NativeReadCallback (IntPtr ptr, IntPtr data, ref IntPtr dataLength)
                {
-                       var handle = GCHandle.FromIntPtr (ptr);
-                       if (!handle.IsAllocated)
-                               return SslStatus.Internal;
+                       AppleTlsContext context = null;
+                       try {
+                               var weakHandle = GCHandle.FromIntPtr (ptr);
+                               if (!weakHandle.IsAllocated)
+                                       return SslStatus.Internal;
 
-                       var context = (AppleTlsContext) handle.Target;
-                       if (context.disposed)
-                               return SslStatus.ClosedAbort;
+                               context = (AppleTlsContext) weakHandle.Target;
+                               if (context == null || context.disposed)
+                                       return SslStatus.ClosedAbort;
 
-                       try {
                                return context.NativeReadCallback (data, ref dataLength);
                        } catch (Exception ex) {
-                               if (context.lastException == null)
+                               if (context != null && context.lastException == null)
                                        context.lastException = ex;
                                return SslStatus.Internal;
                        }
@@ -704,18 +704,19 @@ namespace Mono.AppleTls
                [Mono.Util.MonoPInvokeCallback (typeof (SslWriteFunc))]
                static SslStatus NativeWriteCallback (IntPtr ptr, IntPtr data, ref IntPtr dataLength)
                {
-                       var handle = GCHandle.FromIntPtr (ptr);
-                       if (!handle.IsAllocated)
-                               return SslStatus.Internal;
+                       AppleTlsContext context = null;
+                       try {
+                               var weakHandle = GCHandle.FromIntPtr (ptr);
+                               if (!weakHandle.IsAllocated)
+                                       return SslStatus.Internal;
 
-                       var context = (AppleTlsContext) handle.Target;
-                       if (context.disposed)
-                               return SslStatus.ClosedAbort;
+                               context = (AppleTlsContext) weakHandle.Target;
+                               if (context == null || context.disposed)
+                                       return SslStatus.ClosedAbort;
 
-                       try {
                                return context.NativeWriteCallback (data, ref dataLength);
                        } catch (Exception ex) {
-                               if (context.lastException == null)
+                               if (context != null && context.lastException == null)
                                        context.lastException = ex;
                                return SslStatus.Internal;
                        }