Skip to content

Commit 17fe8ad

Browse files
committed
JSSE: protect from calling freeSSL() while I/O operations are still in progress
1 parent 60a4842 commit 17fe8ad

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.
@@ -2159,12 +2179,12 @@ public synchronized void close() throws IOException {
21592179
/* Connection is closed, free native WOLFSSL session
21602180
* to release native memory earlier than garbage
21612181
* collector might with finalize(), Don't free if we
2162-
* have threads still waiting in poll/select or if
2182+
* have threads still waiting in poll/select, if
21632183
* our WolfSSLInputStream or WolfSSLOutputStream are
2164-
* still open. */
2184+
* still open, or if there are active I/O operations. */
21652185
if (this.ssl != null) {
2166-
if (this.ssl.getThreadsBlockedInPoll() == 0 &&
2167-
ioStreamsAreClosed()) {
2186+
if ((this.ssl.getThreadsBlockedInPoll() == 0) &&
2187+
ioStreamsAreClosed() && (activeOperations.get() == 0)) {
21682188
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
21692189
() -> "calling this.ssl.freeSSL()");
21702190
this.ssl.freeSSL();
@@ -2174,7 +2194,8 @@ public synchronized void close() throws IOException {
21742194
() -> "deferring freeing this.ssl, threads " +
21752195
"blocked in poll: " +
21762196
this.ssl.getThreadsBlockedInPoll() +
2177-
", or streams not closed");
2197+
", streams not closed, or active operations: " +
2198+
activeOperations.get());
21782199
}
21792200
}
21802201

@@ -2714,6 +2735,9 @@ public synchronized int read(byte[] b, int off, int len)
27142735
"Array index out of bounds");
27152736
}
27162737

2738+
/* Enter I/O operation to prevent use-after-free */
2739+
socket.enterIOOperation();
2740+
27172741
try {
27182742
int err;
27192743
int timeout = socket.getSoTimeout();
@@ -2779,6 +2803,9 @@ public synchronized int read(byte[] b, int off, int len)
27792803
* IllegalStateException to be thrown from
27802804
* WolfSSLSession.read(). Return as a SocketException here. */
27812805
throw new SocketException(e.getMessage());
2806+
} finally {
2807+
/* Exit I/O operation */
2808+
socket.exitIOOperation();
27822809
}
27832810

27842811
/* return number of bytes read */
@@ -2925,6 +2952,9 @@ public synchronized void write(byte[] b, int off, int len)
29252952
"Array index out of bounds");
29262953
}
29272954

2955+
/* Enter I/O operation to prevent use-after-free */
2956+
socket.enterIOOperation();
2957+
29282958
try {
29292959
int err;
29302960
int timeout = socket.getSoTimeout();
@@ -2966,6 +2996,9 @@ public synchronized void write(byte[] b, int off, int len)
29662996
() -> "got IllegalStateException: " + e +
29672997
", throwing IOException");
29682998
throw new IOException(e);
2999+
} finally {
3000+
/* Exit I/O operation */
3001+
socket.exitIOOperation();
29693002
}
29703003
}
29713004
} /* end WolfSSLOutputStream inner class */

0 commit comments

Comments
 (0)