cryptomator / cryptofs

Java Filesystem Provider with integrated encryption
GNU Affero General Public License v3.0
93 stars 35 forks source link

Possible invalid ciphertext file when truncate-open a file while concurrently writing to it #165

Closed infeo closed 1 year ago

infeo commented 1 year ago

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 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.