Skip to content

Commit 33d4e7c

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

1 file changed

Lines changed: 43 additions & 5 deletions

File tree

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

Lines changed: 43 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,23 @@ 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 boolean enterIOOperation() {
1979+
activeOperations.incrementAndGet();
1980+
return true;
1981+
}
1982+
1983+
/**
1984+
* Helper method to safely exit an I/O operation.
1985+
* Must be called for every successful enterIOOperation().
1986+
*/
1987+
private void exitIOOperation() {
1988+
activeOperations.decrementAndGet();
1989+
}
1990+
19701991
/**
19711992
* Internal private method to check if WolfSSLInputStream
19721993
* and WolfSSLOutputStream are closed.
@@ -2157,11 +2178,11 @@ public synchronized void close() throws IOException {
21572178
/* Connection is closed, free native WOLFSSL session
21582179
* to release native memory earlier than garbage
21592180
* collector might with finalize(), Don't free if we
2160-
* have threads still waiting in poll/select or if
2181+
* have threads still waiting in poll/select, if
21612182
* our WolfSSLInputStream or WolfSSLOutputStream are
2162-
* still open. */
2163-
if (this.ssl.getThreadsBlockedInPoll() == 0 &&
2164-
ioStreamsAreClosed()) {
2183+
* still open, or if there are active I/O operations. */
2184+
if ((this.ssl.getThreadsBlockedInPoll() == 0) &&
2185+
ioStreamsAreClosed() && (activeOperations.get() == 0)) {
21652186
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
21662187
() -> "calling this.ssl.freeSSL()");
21672188
this.ssl.freeSSL();
@@ -2171,7 +2192,8 @@ public synchronized void close() throws IOException {
21712192
() -> "deferring freeing this.ssl, threads " +
21722193
"blocked in poll: " +
21732194
this.ssl.getThreadsBlockedInPoll() +
2174-
", or streams not closed");
2195+
", streams not closed, or active operations: " +
2196+
activeOperations.get());
21752197
}
21762198

21772199
/* Reset internal WolfSSLEngineHelper to null */
@@ -2710,6 +2732,11 @@ public synchronized int read(byte[] b, int off, int len)
27102732
"Array index out of bounds");
27112733
}
27122734

2735+
/* Enter I/O operation to prevent use-after-free */
2736+
if (!socket.enterIOOperation()) {
2737+
throw new SocketException("Socket is closing");
2738+
}
2739+
27132740
try {
27142741
int err;
27152742
int timeout = socket.getSoTimeout();
@@ -2775,6 +2802,9 @@ public synchronized int read(byte[] b, int off, int len)
27752802
* IllegalStateException to be thrown from
27762803
* WolfSSLSession.read(). Return as a SocketException here. */
27772804
throw new SocketException(e.getMessage());
2805+
} finally {
2806+
/* Exit I/O operation */
2807+
socket.exitIOOperation();
27782808
}
27792809

27802810
/* return number of bytes read */
@@ -2921,6 +2951,11 @@ public synchronized void write(byte[] b, int off, int len)
29212951
"Array index out of bounds");
29222952
}
29232953

2954+
/* Enter I/O operation to prevent use-after-free */
2955+
if (!socket.enterIOOperation()) {
2956+
throw new SocketException("Socket is closing");
2957+
}
2958+
29242959
try {
29252960
int err;
29262961
int timeout = socket.getSoTimeout();
@@ -2962,6 +2997,9 @@ public synchronized void write(byte[] b, int off, int len)
29622997
() -> "got IllegalStateException: " + e +
29632998
", throwing IOException");
29642999
throw new IOException(e);
3000+
} finally {
3001+
/* Exit I/O operation */
3002+
socket.exitIOOperation();
29653003
}
29663004
}
29673005
} /* end WolfSSLOutputStream inner class */

0 commit comments

Comments
 (0)