Skip to content

Commit e022448

Browse files
committed
JSSE: protect from calling freeSSL() while I/O operations are still in progress
1 parent 6acd852 commit e022448

1 file changed

Lines changed: 38 additions & 5 deletions

File tree

src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ public class WolfSSLSocket extends SSLSocket {
8080
private WolfSSLInputStream inStream;
8181
private WolfSSLOutputStream outStream;
8282

83+
/* Track active I/O operations to prevent use-after-free */
84+
private final java.util.concurrent.atomic.AtomicInteger activeOperations =
85+
new java.util.concurrent.atomic.AtomicInteger(0);
86+
8387
private ArrayList<HandshakeCompletedListener> hsListeners = null;
8488

8589
/** TLS handshake initialization called */
@@ -1967,6 +1971,22 @@ public synchronized boolean sessionResumed() throws SSLException {
19671971
return false;
19681972
}
19691973

1974+
/**
1975+
* Helper method to track entry into an I/O operation.
1976+
* Increments the active operation counter to prevent premature freeSSL().
1977+
*/
1978+
private void enterIOOperation() {
1979+
activeOperations.incrementAndGet();
1980+
}
1981+
1982+
/**
1983+
* Helper method to safely exit an I/O operation.
1984+
* Must be called for every successful enterIOOperation().
1985+
*/
1986+
private void exitIOOperation() {
1987+
activeOperations.decrementAndGet();
1988+
}
1989+
19701990
/**
19711991
* Internal private method to check if WolfSSLInputStream
19721992
* and WolfSSLOutputStream are closed.
@@ -2157,11 +2177,11 @@ public synchronized void close() throws IOException {
21572177
/* Connection is closed, free native WOLFSSL session
21582178
* to release native memory earlier than garbage
21592179
* collector might with finalize(), Don't free if we
2160-
* have threads still waiting in poll/select or if
2180+
* have threads still waiting in poll/select, if
21612181
* our WolfSSLInputStream or WolfSSLOutputStream are
2162-
* still open. */
2163-
if (this.ssl.getThreadsBlockedInPoll() == 0 &&
2164-
ioStreamsAreClosed()) {
2182+
* still open, or if there are active I/O operations. */
2183+
if ((this.ssl.getThreadsBlockedInPoll() == 0) &&
2184+
ioStreamsAreClosed() && (activeOperations.get() == 0)) {
21652185
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
21662186
() -> "calling this.ssl.freeSSL()");
21672187
this.ssl.freeSSL();
@@ -2171,7 +2191,8 @@ public synchronized void close() throws IOException {
21712191
() -> "deferring freeing this.ssl, threads " +
21722192
"blocked in poll: " +
21732193
this.ssl.getThreadsBlockedInPoll() +
2174-
", or streams not closed");
2194+
", streams not closed, or active operations: " +
2195+
activeOperations.get());
21752196
}
21762197

21772198
/* Reset internal WolfSSLEngineHelper to null */
@@ -2710,6 +2731,9 @@ public synchronized int read(byte[] b, int off, int len)
27102731
"Array index out of bounds");
27112732
}
27122733

2734+
/* Enter I/O operation to prevent use-after-free */
2735+
socket.enterIOOperation();
2736+
27132737
try {
27142738
int err;
27152739
int timeout = socket.getSoTimeout();
@@ -2775,6 +2799,9 @@ public synchronized int read(byte[] b, int off, int len)
27752799
* IllegalStateException to be thrown from
27762800
* WolfSSLSession.read(). Return as a SocketException here. */
27772801
throw new SocketException(e.getMessage());
2802+
} finally {
2803+
/* Exit I/O operation */
2804+
socket.exitIOOperation();
27782805
}
27792806

27802807
/* return number of bytes read */
@@ -2921,6 +2948,9 @@ public synchronized void write(byte[] b, int off, int len)
29212948
"Array index out of bounds");
29222949
}
29232950

2951+
/* Enter I/O operation to prevent use-after-free */
2952+
socket.enterIOOperation();
2953+
29242954
try {
29252955
int err;
29262956
int timeout = socket.getSoTimeout();
@@ -2962,6 +2992,9 @@ public synchronized void write(byte[] b, int off, int len)
29622992
() -> "got IllegalStateException: " + e +
29632993
", throwing IOException");
29642994
throw new IOException(e);
2995+
} finally {
2996+
/* Exit I/O operation */
2997+
socket.exitIOOperation();
29652998
}
29662999
}
29673000
} /* end WolfSSLOutputStream inner class */

0 commit comments

Comments
 (0)