Description
Hey,
We are currently trying to use cryptofs as the backing filesystem for https://github.com/eclipse-store.
EclipseStore offers a type of transaction object, where you can store
multiple things and then commit
them, flushing them to the storage target.
In this scenario the storage target is a cryptofs instance. When killing the JVM abruptly (not graceful), this will cause broken files that can't be decrypted anymore.
I have created a reproducer repo here:
https://github.com/Bios-Marcel/cryptofs_bug_reproducer
You can switch between the uncrypted and encrypted versions of the reproducer by commenting / uncommenting the respective first line in EclipseStoreMain
.
To cause the issue, you need to kill the JVM after the console puts out Committing
, but before it says Committed
. Given that cryptofs is a filesystem abstraction, I am doubting that EclipseStore does anything wrong here, especially since there is no issue in reading / writing the data without encryption.
Here's the exception:
Exception in thread "main" org.eclipse.store.storage.exceptions.StorageException: Problem in channel #0
at org.eclipse.store.storage.types.StorageChannelTask$Abstract.checkForProblems(StorageChannelTask.java:106)
at org.eclipse.store.storage.types.StorageChannelTask$Abstract.waitOnCompletion(StorageChannelTask.java:168)
at org.eclipse.store.storage.types.StorageSystem$Default.startThreads(StorageSystem.java:332)
at org.eclipse.store.storage.types.StorageSystem$Default.internalStartUp(StorageSystem.java:515)
at org.eclipse.store.storage.types.StorageSystem$Default.start(StorageSystem.java:601)
at org.eclipse.store.storage.types.StorageSystem$Default.start(StorageSystem.java:71)
at org.eclipse.store.storage.embedded.types.EmbeddedStorageManager$Default.start(EmbeddedStorageManager.java:247)
at org.eclipse.store.storage.embedded.types.EmbeddedStorageManager$Default.start(EmbeddedStorageManager.java:95)
at EclipseStoreMain.main(EclipseStoreMain.java:33)
Caused by: org.eclipse.store.storage.exceptions.StorageExceptionIoReading
at org.eclipse.store.storage.types.StorageEntityInitializer$Default.fillBuffer(StorageEntityInitializer.java:279)
at org.eclipse.store.storage.types.StorageEntityInitializer$Default.indexEntities(StorageEntityInitializer.java:181)
at org.eclipse.store.storage.types.StorageEntityInitializer$Default.registerFileEntities(StorageEntityInitializer.java:127)
at org.eclipse.store.storage.types.StorageEntityInitializer$Default.registerEntities(StorageEntityInitializer.java:103)
at org.eclipse.store.storage.types.StorageEntityInitializer$Default.registerEntities(StorageEntityInitializer.java:85)
at org.eclipse.store.storage.types.StorageEntityInitializer$Default.registerEntities(StorageEntityInitializer.java:48)
at org.eclipse.store.storage.types.StorageFileManager$Default.initializeForExistingFiles(StorageFileManager.java:1002)
at org.eclipse.store.storage.types.StorageFileManager$Default.initializeStorage(StorageFileManager.java:886)
at org.eclipse.store.storage.types.StorageChannel$Default.initializeStorage(StorageChannel.java:782)
at org.eclipse.store.storage.types.StorageChannelTaskInitialize$Default.succeed(StorageChannelTaskInitialize.java:200)
at org.eclipse.store.storage.types.StorageChannelTaskInitialize$Default.succeed(StorageChannelTaskInitialize.java:34)
at org.eclipse.store.storage.types.StorageChannelSynchronizingTask$AbstractCompletingTask.synchronizedComplete(StorageChannelSynchronizingTask.java:78)
at org.eclipse.store.storage.types.StorageChannelSynchronizingTask$AbstractCompletingTask.complete(StorageChannelSynchronizingTask.java:126)
at org.eclipse.store.storage.types.StorageChannelTask$Abstract.processBy(StorageChannelTask.java:260)
at org.eclipse.store.storage.types.StorageChannel$Default.work(StorageChannel.java:453)
at org.eclipse.store.storage.types.StorageChannel$Default.run(StorageChannel.java:536)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: org.eclipse.store.storage.exceptions.StorageExceptionIoReading
at org.eclipse.store.storage.types.StorageFile$Abstract.readBytes(StorageFile.java:176)
at org.eclipse.store.storage.types.StorageEntityInitializer$Default.fillBuffer(StorageEntityInitializer.java:275)
... 16 more
Caused by: org.eclipse.serializer.exceptions.IORuntimeException: java.io.IOException: org.cryptomator.cryptolib.api.AuthenticationFailedException: Content tag mismatch.
at org.eclipse.store.afs.nio.types.NioIoHandler$Default.specificReadBytes(NioIoHandler.java:453)
at org.eclipse.store.afs.nio.types.NioIoHandler$Default.specificReadBytes(NioIoHandler.java:81)
at org.eclipse.serializer.afs.types.AIoHandler$Abstract.readBytes(AIoHandler.java:790)
at org.eclipse.serializer.afs.types.AReadableFile.readBytes(AReadableFile.java:104)
at org.eclipse.store.storage.types.StorageFile$Abstract.readBytes(StorageFile.java:172)
... 17 more
Caused by: java.io.IOException: org.cryptomator.cryptolib.api.AuthenticationFailedException: Content tag mismatch.
at org.cryptomator.cryptofs.fh.ChunkCache.getChunk(ChunkCache.java:123)
at org.cryptomator.cryptofs.ch.CleartextFileChannel.readLocked(CleartextFileChannel.java:112)
at org.cryptomator.cryptofs.ch.AbstractFileChannel.read(AbstractFileChannel.java:155)
at org.eclipse.serializer.io.XIO.internalRead(XIO.java:1238)
at org.eclipse.serializer.io.XIO.read(XIO.java:1198)
at org.eclipse.store.afs.nio.types.NioIoHandler$Default.specificReadBytes(NioIoHandler.java:449)
... 21 more
Caused by: org.cryptomator.cryptolib.api.AuthenticationFailedException: Content tag mismatch.
at org.cryptomator.cryptolib.v2.FileContentCryptorImpl.decryptChunk(FileContentCryptorImpl.java:146)
at org.cryptomator.cryptolib.v2.FileContentCryptorImpl.decryptChunk(FileContentCryptorImpl.java:97)
at org.cryptomator.cryptofs.fh.ChunkLoader.load(ChunkLoader.java:40)
at org.cryptomator.cryptofs.fh.ChunkCache.loadChunk(ChunkCache.java:133)
at org.cryptomator.cryptofs.fh.ChunkCache.lambda$getChunk$2(ChunkCache.java:117)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$remap$16(BoundedLocalCache.java:2858)
at java.base/java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1916)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.remap(BoundedLocalCache.java:2853)
at com.github.benmanes.caffeine.cache.BoundedLocalCache.compute(BoundedLocalCache.java:2803)
at com.github.benmanes.caffeine.cache.LocalCache.compute(LocalCache.java:99)
at org.cryptomator.cryptofs.fh.ChunkCache.getChunk(ChunkCache.java:115)
... 26 more
Caused by: javax.crypto.AEADBadTagException: Tag mismatch
at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMDecrypt.doFinal(GaloisCounterMode.java:1652)
at java.base/com.sun.crypto.provider.GaloisCounterMode.engineDoFinal(GaloisCounterMode.java:458)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2543)
at org.cryptomator.cryptolib.v2.FileContentCryptorImpl.decryptChunk(FileContentCryptorImpl.java:143)
... 36 more