From 72ef56652d0a251bfa8e287d6b3a6cbb5b7eef90 Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Tue, 3 Mar 2026 16:18:16 +0100 Subject: [PATCH] Fix race condition in pfs_reopen_file_for_writing encoder state (#329) Crypto folder operations tested, no regression --- pclsync/pfs.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pclsync/pfs.c b/pclsync/pfs.c index 78af7ee..ecb8d6f 100644 --- a/pclsync/pfs.c +++ b/pclsync/pfs.c @@ -2130,17 +2130,24 @@ pfs_reopen_file_for_writing(psync_openfile_t *of) { if (unlikely(of->encrypted && of->encoder == PSYNC_CRYPTO_UNLOADED_SECTOR_ENCODER)) { pcrypto_sector_encdec_t enc; + psync_fsfileid_t remotefileid; + uint64_t hash; + // Save values before unlock + remotefileid = of->remotefileid; + hash = of->hash; // we should unlock of->mutex as it can deadlock with sqllock and taking // sqllock before network operation is not a good idea pthread_mutex_unlock(&of->mutex); - enc = pcryptofolder_filencoder_get(of->remotefileid, of->hash, 0); + enc = pcryptofolder_filencoder_get(remotefileid, hash, 0); if (unlikely(psync_crypto_is_error(enc))) return -pfs_crypto_err_to_errno(psync_crypto_to_error(enc)); pfs_lock_file(of); - if (of->encoder == PSYNC_CRYPTO_UNLOADED_SECTOR_ENCODER) + // Check if state changed while unlocked + if (of->encoder == PSYNC_CRYPTO_UNLOADED_SECTOR_ENCODER && + of->remotefileid == remotefileid && of->hash == hash) of->encoder = enc; else - pcryptofolder_filencoder_release(of->remotefileid, of->hash, enc); + pcryptofolder_filencoder_release(remotefileid, hash, enc); if (of->newfile || of->modified) return 1; }