From 3a6104dda1e4947e8f9f1148fdaf902ba31b0643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Csahvx655-wq=E2=80=9D?= <“sahvx655@gmail.com”> Date: Fri, 29 May 2026 12:31:09 +0530 Subject: [PATCH] Ensure atomic session persistence in FileStore using write-then-rename pattern --- java/org/apache/catalina/session/FileStore.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/java/org/apache/catalina/session/FileStore.java b/java/org/apache/catalina/session/FileStore.java index 0ec92f10c522..b576206f88a5 100644 --- a/java/org/apache/catalina/session/FileStore.java +++ b/java/org/apache/catalina/session/FileStore.java @@ -269,13 +269,21 @@ public void save(Session session) throws IOException { .trace(sm.getString(getStoreName() + ".saving", session.getIdInternal(), file.getAbsolutePath())); } + File tempFile = new File(file.getAbsolutePath() + ".tmp"); + Lock writeLock = sessionLocksById.getLock(session.getIdInternal()).writeLock(); writeLock.lock(); try { - try (FileOutputStream fos = new FileOutputStream(file.getAbsolutePath()); + try (FileOutputStream fos = new FileOutputStream(tempFile); ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos))) { ((StandardSession) session).writeObjectData(oos); } + if (!tempFile.renameTo(file)) { + if (tempFile.exists() && !tempFile.delete()) { + log.warn(sm.getString("fileStore.deleteFailed", tempFile)); + } + throw new IOException(sm.getString("fileStore.renameFailed", tempFile, file)); + } } finally { writeLock.unlock(); }