Skip to content

Commit 1df38d2

Browse files
authored
Fix race when handling delegating tasks in ReferenceCountedOpenSslEngine (#12149)
Motivation: Due incorrect handling of delegating tasks in ReferenceCountedOpenSslEngine it was possible to observe handshake timeouts / failures. Modification: - Only reset needsTask variable after we actually ran the task. - Add missing synchronized as otherwise we might end up calling native code concurrently which is not safe. - Change how we excute delegating tasks in our SSLEngineTest. This change would result in timeouts / failures before the fix. Result: Fixes #12139
1 parent 673849d commit 1df38d2

2 files changed

Lines changed: 17 additions & 20 deletions

File tree

handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,13 +1456,7 @@ private class TaskDecorator<R extends Runnable> implements Runnable {
14561456

14571457
@Override
14581458
public void run() {
1459-
if (isDestroyed()) {
1460-
// The engine was destroyed in the meantime, just return.
1461-
return;
1462-
}
1463-
// The task was run, reset needTask to false so getHandshakeStatus() returns the correct value.
1464-
needTask = false;
1465-
task.run();
1459+
runAndResetNeedTask(task);
14661460
}
14671461
}
14681462

@@ -1475,19 +1469,22 @@ private final class AsyncTaskDecorator extends TaskDecorator<AsyncTask> implemen
14751469
public void run(final Runnable runnable) {
14761470
if (isDestroyed()) {
14771471
// The engine was destroyed in the meantime, just return.
1478-
runnable.run();
14791472
return;
14801473
}
1481-
task.runAsync(new Runnable() {
1482-
@Override
1483-
public void run() {
1484-
// The task was run, reset needTask to false so getHandshakeStatus() returns the correct value.
1485-
// This needs to be done before we run the completion runnable, since that might
1486-
// query the handshake status.
1487-
needTask = false;
1488-
runnable.run();
1489-
}
1490-
});
1474+
task.runAsync(new TaskDecorator<Runnable>(runnable));
1475+
}
1476+
}
1477+
1478+
private synchronized void runAndResetNeedTask(Runnable task) {
1479+
try {
1480+
if (isDestroyed()) {
1481+
// The engine was destroyed in the meantime, just return.
1482+
return;
1483+
}
1484+
task.run();
1485+
} finally {
1486+
// The task was run, reset needTask to false so getHandshakeStatus() returns the correct value.
1487+
needTask = false;
14911488
}
14921489
}
14931490

handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,7 +1712,7 @@ private static boolean isHandshakeFinished(SSLEngineResult result) {
17121712
return result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED;
17131713
}
17141714

1715-
private void runDelegatedTasks(boolean delegate, SSLEngineResult result, SSLEngine engine) throws Exception {
1715+
private void runDelegatedTasks(boolean delegate, SSLEngineResult result, SSLEngine engine) {
17161716
if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
17171717
for (;;) {
17181718
Runnable task = engine.getDelegatedTask();
@@ -1722,7 +1722,7 @@ private void runDelegatedTasks(boolean delegate, SSLEngineResult result, SSLEngi
17221722
if (!delegate) {
17231723
task.run();
17241724
} else {
1725-
delegatingExecutor.submit(task).get();
1725+
delegatingExecutor.execute(task);
17261726
}
17271727
}
17281728
}

0 commit comments

Comments
 (0)