This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new f866633d21 Fix potential deadlock on copy
f866633d21 is described below

commit f866633d21f32995e2dbd2a09f243f100e7f1645
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Jun 10 11:29:02 2026 +0100

    Fix potential deadlock on copy
---
 java/org/apache/catalina/servlets/WebdavServlet.java | 18 ++++++++++++++++--
 webapps/docs/changelog.xml                           |  3 +++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/catalina/servlets/WebdavServlet.java 
b/java/org/apache/catalina/servlets/WebdavServlet.java
index 2de1fa80f7..d3c0245c9f 100644
--- a/java/org/apache/catalina/servlets/WebdavServlet.java
+++ b/java/org/apache/catalina/servlets/WebdavServlet.java
@@ -2987,8 +2987,22 @@ public class WebdavServlet extends DefaultServlet 
implements PeriodicEventListen
                     propertiesDest = new ArrayList<>();
                     deadProperties.put(destination, propertiesDest);
                 }
-                synchronized (properties) {
-                    synchronized (propertiesDest) {
+                /*
+                 * The following ensures that locks for any two paths are 
always obtained in the same other order
+                 * regardless of which is the source and which is the 
destination. This is to avoid deadlocks for
+                 * concurrent calls where source and destination are reversed.
+                 */
+                Object lockFirst;
+                Object lockSecond;
+                if (source.compareTo(destination) > 0) {
+                    lockFirst = properties;
+                    lockSecond = propertiesDest;
+                } else {
+                    lockFirst = propertiesDest;
+                    lockSecond = properties;
+                }
+                synchronized (lockFirst) {
+                    synchronized (lockSecond) {
                         for (Node node : properties) {
                             node = node.cloneNode(true);
                             boolean found = false;
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 44168590bb..42d8bdaa5d 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -264,6 +264,9 @@
         <code>server.xml</code>. Cluster digester rules are now fully
         conditional on both JARs being available. (dsoumis)
       </fix>
+      <fix>
+        Fix a potential deadlock when copying resources using WebDAV. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to