CryptoFs manages per encrypted file several (cleartext, ciphertext)-filechannelpairs. Hence, it is possible, that while one filechannel is continuously writing to an encrypted file, a different file channel opens the same file with the TRUNCATE_EXISTING flag.
Keep in mind, that Thread t1 writes in the background continuously to the file. When thread t2 now opens a new file channel to the same file with TRUNCATE_EXISTING, it will end up in the above code of OpenCryptoFile::newFileChannel. In line 78 the ciphertextfilechannel with the trunacte flag is opened, and in line 81 we decide what file header we use based on the size of the encrypted file.
If between these two steps thread t2 is hibernated and t1 flushes its content, the size of the encrypted file is != 0 and no new header is used. But on the other hand we truncated the encrytped file, so nilling any the existing fileheader on storage side. And since we set newHeader = false, the header won't get written anymore, making the file undecryptable.
CryptoFs manages per encrypted file several (cleartext, ciphertext)-filechannelpairs. Hence, it is possible, that while one filechannel is continuously writing to an encrypted file, a different file channel opens the same file with the
TRUNCATE_EXISTING
flag.This can lead to a rare race condition: https://github.com/cryptomator/cryptofs/blob/32650a9737db562a1e49fce798c46ba2bc010f69/src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java#L78-L91
Keep in mind, that Thread t1 writes in the background continuously to the file. When thread t2 now opens a new file channel to the same file with
TRUNCATE_EXISTING
, it will end up in the above code ofOpenCryptoFile::newFileChannel
. In line 78 the ciphertextfilechannel with the trunacte flag is opened, and in line 81 we decide what file header we use based on the size of the encrypted file.If between these two steps thread t2 is hibernated and t1 flushes its content, the size of the encrypted file is != 0 and no new header is used. But on the other hand we truncated the encrytped file, so nilling any the existing fileheader on storage side. And since we set
newHeader = false
, the header won't get written anymore, making the file undecryptable.