- 
                Notifications
    You must be signed in to change notification settings 
- Fork 35
Closed
Milestone
Description
Summary
Library version: 2.7.1
Truncating a channel which is currently written to can create invalid ciphertext/unreadable file.
Description
In our test suite exists a test, which truncates a file while another thread writes data to the same file:
cryptofs/src/test/java/org/cryptomator/cryptofs/CryptoFileChannelWriteReadIntegrationTest.java
Lines 620 to 647 in 4d6a56b
| public void testConcurrentWriteAndTruncate() throws IOException { | |
| AtomicBoolean keepWriting = new AtomicBoolean(true); | |
| ByteBuffer buf = ByteBuffer.wrap("the quick brown fox jumps over the lazy dog".getBytes(StandardCharsets.UTF_8)); | |
| var executor = Executors.newCachedThreadPool(); | |
| try (FileChannel writingChannel = FileChannel.open(file, WRITE, CREATE)) { | |
| executor.submit(() -> { | |
| while (keepWriting.get()) { | |
| try { | |
| writingChannel.write(buf); | |
| } catch (IOException e) { | |
| throw new UncheckedIOException(e); | |
| } | |
| buf.flip(); | |
| } | |
| }); | |
| try (FileChannel truncatingChannel = FileChannel.open(file, WRITE, TRUNCATE_EXISTING)) { | |
| keepWriting.set(false); | |
| } | |
| executor.shutdown(); | |
| } | |
| Assertions.assertDoesNotThrow(() -> { | |
| try (FileChannel readingChannel = FileChannel.open(file, READ)) { | |
| var dst = ByteBuffer.allocate(buf.capacity()); | |
| readingChannel.read(dst); | |
| } | |
| }); | |
| } | 
This test fails in very rare cases, e.g. in CI run 12694328432. If the logs are not available anymore, you can download them here
You can trigger the failure with higher probability, if you add a new line after line 634 with Thread.sleep(2000);.