Skip to content

Commit e23ff98

Browse files
authored
Merge pull request #278 from cconlon/sslSocketFreeFix
JSSE: protect from calling freeSSL() while I/O operations in progress
2 parents 04190d9 + 17fe8ad commit e23ff98

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 */
@@ -1972,6 +1976,22 @@ public synchronized boolean sessionResumed() throws SSLException {
19721976
return false;
19731977
}
19741978

1979+
/**
1980+
* Helper method to track entry into an I/O operation.
1981+
* Increments the active operation counter to prevent premature freeSSL().
1982+
*/
1983+
private void enterIOOperation() {
1984+
activeOperations.incrementAndGet();
1985+
}
1986+
1987+
/**
1988+
* Helper method to safely exit an I/O operation.
1989+
* Must be called for every successful enterIOOperation().
1990+
*/
1991+
private void exitIOOperation() {
1992+
activeOperations.decrementAndGet();
1993+
}
1994+
19751995
/**
19761996
* Internal private method to check if WolfSSLInputStream
19771997
* and WolfSSLOutputStream are closed.
@@ -2168,12 +2188,12 @@ public synchronized void close() throws IOException {
21682188
/* Connection is closed, free native WOLFSSL session
21692189
* to release native memory earlier than garbage
21702190
* collector might with finalize(), Don't free if we
2171-
* have threads still waiting in poll/select or if
2191+
* have threads still waiting in poll/select, if
21722192
* our WolfSSLInputStream or WolfSSLOutputStream are
2173-
* still open. */
2193+
* still open, or if there are active I/O operations. */
21742194
if (this.ssl != null) {
2175-
if (this.ssl.getThreadsBlockedInPoll() == 0 &&
2176-
ioStreamsAreClosed()) {
2195+
if ((this.ssl.getThreadsBlockedInPoll() == 0) &&
2196+
ioStreamsAreClosed() && (activeOperations.get() == 0)) {
21772197
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
21782198
() -> "calling this.ssl.freeSSL()");
21792199
this.ssl.freeSSL();
@@ -2183,7 +2203,8 @@ public synchronized void close() throws IOException {
21832203
() -> "deferring freeing this.ssl, threads " +
21842204
"blocked in poll: " +
21852205
this.ssl.getThreadsBlockedInPoll() +
2186-
", or streams not closed");
2206+
", streams not closed, or active operations: " +
2207+
activeOperations.get());
21872208
}
21882209
}
21892210

@@ -2725,6 +2746,9 @@ public synchronized int read(byte[] b, int off, int len)
27252746
"Array index out of bounds");
27262747
}
27272748

2749+
/* Enter I/O operation to prevent use-after-free */
2750+
socket.enterIOOperation();
2751+
27282752
try {
27292753
int err;
27302754
int timeout = socket.getSoTimeout();
@@ -2790,6 +2814,9 @@ public synchronized int read(byte[] b, int off, int len)
27902814
* IllegalStateException to be thrown from
27912815
* WolfSSLSession.read(). Return as a SocketException here. */
27922816
throw new SocketException(e.getMessage());
2817+
} finally {
2818+
/* Exit I/O operation */
2819+
socket.exitIOOperation();
27932820
}
27942821

27952822
/* return number of bytes read */
@@ -2936,6 +2963,9 @@ public synchronized void write(byte[] b, int off, int len)
29362963
"Array index out of bounds");
29372964
}
29382965

2966+
/* Enter I/O operation to prevent use-after-free */
2967+
socket.enterIOOperation();
2968+
29392969
try {
29402970
int err;
29412971
int timeout = socket.getSoTimeout();
@@ -2977,6 +3007,9 @@ public synchronized void write(byte[] b, int off, int len)
29773007
() -> "got IllegalStateException: " + e +
29783008
", throwing IOException");
29793009
throw new IOException(e);
3010+
} finally {
3011+
/* Exit I/O operation */
3012+
socket.exitIOOperation();
29803013
}
29813014
}
29823015
} /* end WolfSSLOutputStream inner class */

0 commit comments

Comments
 (0)