diff --git a/SOURCES/patch.rhbz1602060 b/SOURCES/patch.rhbz1602060 new file mode 100644 index 0000000..e89aadf --- /dev/null +++ b/SOURCES/patch.rhbz1602060 @@ -0,0 +1,82 @@ +--- java/org/apache/tomcat/websocket/WsSession.java.org 2017-03-09 14:51:41.000000000 +0100 ++++ java/org/apache/tomcat/websocket/WsSession.java 2018-07-18 17:37:46.853657200 +0200 +@@ -595,8 +595,8 @@ + localEndpoint.onError(this, e); + } + } +- +- ++ ++ + /** + * Use protected so unit tests can access this method directly. + */ +@@ -635,29 +635,48 @@ + * {@link FutureToSendHandler} completes. + */ + protected void registerFuture(FutureToSendHandler f2sh) { +- boolean fail = false; +- synchronized (stateLock) { +- // If the session has already been closed the any registered futures +- // will have been processed so the failure result for this future +- // needs to be set here. +- if (state == State.OPEN || f2sh.isCloseMessage()) { +- // WebSocket session is open or this is the close message +- futures.put(f2sh, f2sh); +- } else if (f2sh.isDone()) { +- // NO-OP. The future completed before the session closed so no +- // need to register in case the session closes before it +- // completes. +- } else { +- // Construct the exception outside of the sync block +- fail = true; +- } ++ // Ideally, this code should sync on stateLock so that the correct ++ // action is taken based on the current state of the connection. ++ // However, a sync on stateLock can't be used here as it will create the ++ // possibility of a dead-lock. See BZ 61183. ++ // Therefore, a slightly less efficient approach is used. ++ ++ // Always register the future. ++ futures.put(f2sh, f2sh); ++ ++ if (state == State.OPEN || f2sh.isCloseMessage()) { ++ // The session is open. The future has been registered with the open ++ // session. Normal processing continues. ++ return; + } + +- if (fail) { +- IOException ioe = new IOException(sm.getString("wsSession.messageFailed")); +- SendResult sr = new SendResult(ioe); +- f2sh.onResult(sr); ++ // The session is closed. The future may or may not have been registered ++ // in time for it to be processed during session closure. ++ ++ if (f2sh.isDone()) { ++ // The future has completed. It is not known if the future was ++ // completed normally by the I/O layer or in error by doClose(). It ++ // doesn't matter which. There is nothing more to do here. ++ return; + } ++ ++ // The session is closed. The Future had not completed when last checked. ++ // There is a small timing window that means the Future may have been ++ // completed since the last check. There is also the possibility that ++ // the Future was not registered in time to be cleaned up during session ++ // close. ++ // Attempt to complete the Future with an error result as this ensures ++ // that the Future completes and any client code waiting on it does not ++ // hang. It is slightly inefficient since the Future may have been ++ // completed in another thread or another thread may be about to ++ // complete the Future but knowing if this is the case requires the sync ++ // on stateLock (see above). ++ // Note: If multiple attempts are made to complete the Future, the ++ // second and subsequent attempts are ignored. ++ ++ IOException ioe = new IOException(sm.getString("wsSession.messageFailed")); ++ SendResult sr = new SendResult(ioe); ++ f2sh.onResult(sr); + } + + diff --git a/SPECS/tomcat.spec b/SPECS/tomcat.spec index 7a5ff00..8155505 100644 --- a/SPECS/tomcat.spec +++ b/SPECS/tomcat.spec @@ -54,7 +54,7 @@ Name: tomcat Epoch: 0 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 6%{?dist} +Release: 7%{?dist} Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API Group: System Environment/Daemons @@ -92,6 +92,7 @@ Patch4: %{name}-7.0.76-CVE-2017-5664.patch Patch5: %{name}-7.0.76-CVE-2017-5647.patch Patch6: %{name}-7.0.76-CVE-2017-7674.patch Patch7: %{name}-7.0.76-CVE-2017-12617.patch +Patch8: patch.rhbz1602060 BuildArch: noarch @@ -244,6 +245,7 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name " %patch5 -p0 %patch6 -p0 %patch7 -p0 +%patch8 -p0 %{__ln_s} $(build-classpath jakarta-taglibs-core) webapps/examples/WEB-INF/lib/jstl.jar %{__ln_s} $(build-classpath jakarta-taglibs-standard) webapps/examples/WEB-INF/lib/standard.jar @@ -688,6 +690,9 @@ fi %attr(0644,root,root) %{_unitdir}/%{name}-jsvc.service %changelog +* Wed Jul 18 2018 Jean-Frederic Clere 0:7.0.76-7 +- Resolves: rhbz#1607893 Deadlock occurs while sending to a closing session. + * Wed Nov 08 2017 Coty Sutherland 0:7.0.76-6 - Related: rhbz#1505762 Remove erroneous useradd