From b98978f1203f9f0b61d50d2d98dfd26f2d9580dd Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 28 Apr 2020 12:09:30 -0400 Subject: [PATCH] import jss-4.6.2-6.module+el8.2.0+6305+445d7b5a --- SOURCES/0005-Fix-NativeProxy-release.patch | 147 +++++++++++++++++++++ SOURCES/0006-Fix-SSLSocket-closure.patch | 108 +++++++++++++++ SPECS/jss.spec | 13 +- 3 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0005-Fix-NativeProxy-release.patch create mode 100644 SOURCES/0006-Fix-SSLSocket-closure.patch diff --git a/SOURCES/0005-Fix-NativeProxy-release.patch b/SOURCES/0005-Fix-NativeProxy-release.patch new file mode 100644 index 0000000..e279abd --- /dev/null +++ b/SOURCES/0005-Fix-NativeProxy-release.patch @@ -0,0 +1,147 @@ +From e623f14abcee16b5dfc57d6956e0ab4bb526ba5b Mon Sep 17 00:00:00 2001 +From: Alexander Scheel +Date: Wed, 8 Apr 2020 12:21:49 -0400 +Subject: [PATCH] Fix NativeProxy registry tracking + +When the switch was made to a HashSet-based registry in +eb5df01003d74b57473eacb84e538d31f5bb06ca, NativeProxy didn't override +hashCode(...). This resulted in calls to close() (and thus, finalize()) +not invoking the releaseNativeResources() function to release the +underlying memory. + +Signed-off-by: Alexander Scheel +--- + org/mozilla/jss/util/NativeProxy.java | 55 +++++++++++++++++++++------ + 1 file changed, 44 insertions(+), 11 deletions(-) + +diff --git a/org/mozilla/jss/util/NativeProxy.java b/org/mozilla/jss/util/NativeProxy.java +index a0811f76..385c49f9 100644 +--- a/org/mozilla/jss/util/NativeProxy.java ++++ b/org/mozilla/jss/util/NativeProxy.java +@@ -9,8 +9,10 @@ import java.util.HashSet; + import java.lang.AutoCloseable; + import java.lang.Thread; + import java.util.Arrays; ++import java.util.concurrent.atomic.AtomicInteger; + + import org.mozilla.jss.CryptoManager; ++import org.mozilla.jss.netscape.security.util.Utils; + + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; +@@ -39,11 +41,13 @@ public abstract class NativeProxy implements AutoCloseable + * NativeProxy instance acts as a proxy for that native data structure. + */ + public NativeProxy(byte[] pointer) { +- assert(pointer!=null); ++ assert(pointer!=null); ++ + mPointer = pointer; +- registry.add(this); ++ mHashCode = registryIndex.getAndIncrement(); + + if (saveStacktraces) { ++ registry.add(this); + mTrace = Arrays.toString(Thread.currentThread().getStackTrace()); + } + } +@@ -55,18 +59,31 @@ public abstract class NativeProxy implements AutoCloseable + * a different underlying native pointer. + */ + public boolean equals(Object obj) { +- if(obj==null) { ++ if (obj == null) { + return false; + } +- if( ! (obj instanceof NativeProxy) ) { ++ if (!(obj instanceof NativeProxy)) { + return false; + } +- if (((NativeProxy)obj).mPointer == null) { +- /* If mPointer is null, we have no way to compare the values +- * of the pointers, so assume they're unequal. */ ++ NativeProxy nObj = (NativeProxy) obj; ++ if (this.mPointer == null || nObj.mPointer == null) { + return false; + } +- return Arrays.equals(((NativeProxy)obj).mPointer, mPointer); ++ ++ return Arrays.equals(this.mPointer, nObj.mPointer); ++ } ++ ++ /** ++ * Hash code based around mPointer value. ++ * ++ * Note that Object.hashCode() isn't sufficient as it tries to determine ++ * the Object's value based on all internal variables. Because we want a ++ * single static hashCode that is unique to each instance of nativeProxy, ++ * we construct it up front based on an incrementing counter and cache it ++ * throughout the lifetime of this object. ++ */ ++ public int hashCode() { ++ return mHashCode; + } + + /** +@@ -112,11 +129,11 @@ public abstract class NativeProxy implements AutoCloseable + */ + public final void close() throws Exception { + try { +- if (registry.remove(this)) { ++ if (mPointer != null) { + releaseNativeResources(); + } + } finally { +- mPointer = null; ++ clear(); + } + } + +@@ -131,13 +148,16 @@ public abstract class NativeProxy implements AutoCloseable + */ + public final void clear() { + this.mPointer = null; +- registry.remove(this); ++ if (saveStacktraces) { ++ registry.remove(this); ++ } + } + + /** + * Byte array containing native pointer bytes. + */ + private byte mPointer[]; ++ private int mHashCode; + + /** + * String containing backtrace of pointer generation. +@@ -158,6 +178,15 @@ public abstract class NativeProxy implements AutoCloseable + * releaseNativeResources() gets called. + */ + static HashSet registry = new HashSet(); ++ static AtomicInteger registryIndex = new AtomicInteger(); ++ ++ public String toString() { ++ if (mPointer == null) { ++ return this.getClass().getName() + "[" + mHashCode + "@null]"; ++ } ++ ++ return this.getClass().getName() + "[" + mHashCode + "@" + Utils.HexEncode(mPointer) + "]"; ++ } + + /** + * Internal helper to check whether or not assertions are enabled in the +@@ -178,6 +207,10 @@ public abstract class NativeProxy implements AutoCloseable + * is thrown. + */ + public synchronized static void assertRegistryEmpty() { ++ if (!saveStacktraces) { ++ return; ++ } ++ + if (!registry.isEmpty()) { + logger.warn(registry.size() + " NativeProxys are still registered."); + +-- +2.25.2 + diff --git a/SOURCES/0006-Fix-SSLSocket-closure.patch b/SOURCES/0006-Fix-SSLSocket-closure.patch new file mode 100644 index 0000000..f7a401c --- /dev/null +++ b/SOURCES/0006-Fix-SSLSocket-closure.patch @@ -0,0 +1,108 @@ +From 278ff534e0a30cb112e8c29de573bf45b4264ad2 Mon Sep 17 00:00:00 2001 +From: Alexander Scheel +Date: Wed, 15 Apr 2020 08:20:37 -0400 +Subject: [PATCH] Fix SSLSocket closure + +Signed-off-by: Alexander Scheel +--- + org/mozilla/jss/ssl/SocketBase.java | 14 +++++++++++- + org/mozilla/jss/ssl/common.c | 34 +++++++++++++++++++---------- + 2 files changed, 36 insertions(+), 12 deletions(-) + +diff --git a/org/mozilla/jss/ssl/SocketBase.java b/org/mozilla/jss/ssl/SocketBase.java +index 2c835913..27109369 100644 +--- a/org/mozilla/jss/ssl/SocketBase.java ++++ b/org/mozilla/jss/ssl/SocketBase.java +@@ -106,7 +106,19 @@ class SocketBase { + static final int SSL_AF_INET6 = 51; + + void close() throws IOException { +- socketClose(); ++ try { ++ if (sockProxy != null) { ++ socketClose(); ++ sockProxy.close(); ++ } ++ } catch (Exception e) { ++ String msg = "Unexpected exception while trying to finalize "; ++ msg += "SocketProxy: " + e.getMessage(); ++ ++ throw new IOException(msg, e); ++ } finally { ++ sockProxy = null; ++ } + } + + // SSLServerSocket and SSLSocket close methods +diff --git a/org/mozilla/jss/ssl/common.c b/org/mozilla/jss/ssl/common.c +index 2db9fda1..2c52a9d6 100644 +--- a/org/mozilla/jss/ssl/common.c ++++ b/org/mozilla/jss/ssl/common.c +@@ -333,21 +333,28 @@ JNIEXPORT void JNICALL + Java_org_mozilla_jss_ssl_SocketProxy_releaseNativeResources + (JNIEnv *env, jobject this) + { +- /* SSLSocket.close and SSLServerSocket.close call */ +- /* SocketBase.close to destroy all native Resources */ +- /* attached to the socket. There is no native resource */ +- /* to release after close has been called. This method */ +- /* remains because SocketProxy extends org.mozilla.jss.util.NativeProxy*/ +- /* which defines releaseNativeResources as abstract and */ +- /* therefore must be implemented by SocketProxy */ ++ JSSL_SocketData *sockdata; ++ ++ PR_ASSERT(env != NULL && this != NULL); ++ ++ if (JSS_getPtrFromProxy(env, this, (void**)&sockdata) != PR_SUCCESS) { ++ return; ++ } ++ ++ JSSL_DestroySocketData(env, sockdata); + } + + void + JSSL_DestroySocketData(JNIEnv *env, JSSL_SocketData *sd) + { +- PR_ASSERT(sd != NULL); ++ if (sd == NULL) { ++ return; ++ } + +- PR_Close(sd->fd); ++ if (sd->fd != NULL) { ++ PR_Close(sd->fd); ++ sd->fd = NULL; ++ } + + if( sd->socketObject != NULL ) { + DELETE_WEAK_GLOBAL_REF(env, sd->socketObject ); +@@ -367,6 +374,8 @@ JSSL_DestroySocketData(JNIEnv *env, JSSL_SocketData *sd) + if( sd->lock != NULL ) { + PR_DestroyLock(sd->lock); + } ++ ++ memset(sd, 0, sizeof(JSSL_SocketData)); + PR_Free(sd); + } + +@@ -540,12 +549,15 @@ Java_org_mozilla_jss_ssl_SocketBase_socketClose(JNIEnv *env, jobject self) + JSSL_SocketData *sock = NULL; + + /* get the FD */ +- if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) { ++ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS || sock == NULL) { + /* exception was thrown */ + return; + } + +- JSSL_DestroySocketData(env, sock); ++ if (sock->fd != NULL) { ++ PR_Close(sock->fd); ++ sock->fd = NULL; ++ } + } + + JNIEXPORT void JNICALL +-- +2.25.2 + diff --git a/SPECS/jss.spec b/SPECS/jss.spec index 87baafc..172f73e 100644 --- a/SPECS/jss.spec +++ b/SPECS/jss.spec @@ -7,7 +7,7 @@ URL: http://www.dogtagpki.org/wiki/JSS License: MPLv1.1 or GPLv2+ or LGPLv2+ Version: 4.6.2 -Release: 4%{?_timestamp}%{?_commit_id}%{?dist} +Release: 6%{?_timestamp}%{?_commit_id}%{?dist} # global _phase -a1 # To generate the source tarball: @@ -29,6 +29,8 @@ Patch0: 0001-Fix-NativeProxy-reference-tracker.patch Patch1: 0002-Fix-swapped-parameter-names-with-PBE.patch Patch3: 0003-Use-specified-algorithm-for-KeyWrap.patch Patch4: 0004-Remove-token-key-checks.patch +Patch5: 0005-Fix-NativeProxy-release.patch +Patch6: 0006-Fix-SSLSocket-closure.patch ################################################################################ # Build Dependencies @@ -163,6 +165,15 @@ cp -p *.txt $RPM_BUILD_ROOT%{_javadocdir}/%{name}-%{version} ################################################################################ %changelog +* Wed Apr 15 2020 Red Hat PKI Team 4.6.2-6 +- NativeProxy never calls releaseNativeResources - Memory Leak + Additional patch to fix SSLSocket resource freeing + Bugzilla #1822402 + +* Tue Apr 14 2020 Red Hat PKI Team 4.6.2-5 +- NativeProxy never calls releaseNativeResources - Memory Leak + Bugzilla #1822402 + * Mon Mar 23 2020 Red Hat PKI Team 4.6.2-4 - Red Hat Bugzilla #1807371 - KRA-HSM: Async and sync key recovery using kra agent web is failing