Skip to content

Truncating a channel which is currently written can create invalid ciphertext #269

@infeo

Description

@infeo

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:

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions