Check checksum before decompressing data

patch by Benjamin Lerer; reviewed by Branimir Lambov and  Gil Tene for 
CASSANDRA-14284


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/34a1d5da
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/34a1d5da
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/34a1d5da

Branch: refs/heads/cassandra-3.11
Commit: 34a1d5da58fb8edcad39633084541bb4162f5ede
Parents: 19d26bc
Author: Benjamin Lerer <b.le...@gmail.com>
Authored: Tue Apr 10 09:42:52 2018 +0200
Committer: Benjamin Lerer <b.le...@gmail.com>
Committed: Tue Apr 10 09:42:52 2018 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../compress/CompressedRandomAccessReader.java  | 37 ++++++++++----------
 2 files changed, 20 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/34a1d5da/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 0c25388..aeb3009 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.1.21
+ * Check checksum before decompressing data (CASSANDRA-14284)
  * CVE-2017-5929 Security vulnerability in Logback warning in NEWS.txt 
(CASSANDRA-14183)
 
 2.1.20

http://git-wip-us.apache.org/repos/asf/cassandra/blob/34a1d5da/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java 
b/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java
index 184db9c..fe90cc9 100644
--- 
a/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java
+++ 
b/src/java/org/apache/cassandra/io/compress/CompressedRandomAccessReader.java
@@ -29,7 +29,6 @@ import 
org.apache.cassandra.io.sstable.CorruptSSTableException;
 import org.apache.cassandra.io.util.CompressedPoolingSegmentedFile;
 import org.apache.cassandra.io.util.PoolingSegmentedFile;
 import org.apache.cassandra.io.util.RandomAccessReader;
-import org.apache.cassandra.utils.FBUtilities;
 
 /**
  * CRAR extends RAR to transparently uncompress blocks from the file into 
RAR.buffer.  Most of the RAR
@@ -107,6 +106,11 @@ public class CompressedRandomAccessReader extends 
RandomAccessReader
         // technically flip() is unnecessary since all the remaining work uses 
the raw array, but if that changes
         // in the future this will save a lot of hair-pulling
         compressed.flip();
+
+        // If the checksum is on compressed data we want to check it before 
uncompressing the data
+        if (metadata.hasPostCompressionAdlerChecksums)
+            checkChecksumIfNeeded(chunk, compressed.array(), chunk.length);
+
         try
         {
             validBufferBytes = 
metadata.compressor().uncompress(compressed.array(), 0, chunk.length, buffer, 
0);
@@ -116,24 +120,9 @@ public class CompressedRandomAccessReader extends 
RandomAccessReader
             throw new CorruptBlockException(getPath(), chunk, e);
         }
 
-        if (metadata.parameters.getCrcCheckChance() > 
ThreadLocalRandom.current().nextDouble())
-        {
-
-            if (metadata.hasPostCompressionAdlerChecksums)
-            {
-                checksum.update(compressed.array(), 0, chunk.length);
-            }
-            else
-            {
-                checksum.update(buffer, 0, validBufferBytes);
-            }
+        if (!metadata.hasPostCompressionAdlerChecksums)
+            checkChecksumIfNeeded(chunk, buffer, validBufferBytes);
 
-            if (checksum(chunk) != (int) checksum.getValue())
-                throw new CorruptBlockException(getPath(), chunk);
-
-            // reset checksum object back to the original (blank) state
-            checksum.reset();
-        }
 
         // buffer offset is always aligned
         bufferOffset = current & ~(buffer.length - 1);
@@ -143,6 +132,18 @@ public class CompressedRandomAccessReader extends 
RandomAccessReader
             validBufferBytes = (int)(length() - bufferOffset);
     }
 
+    private void checkChecksumIfNeeded(CompressionMetadata.Chunk chunk, byte[] 
bytes, int length) throws IOException
+    {
+        if (metadata.parameters.getCrcCheckChance() > 
ThreadLocalRandom.current().nextDouble())
+        {
+            checksum.update(bytes, 0, length);
+            if (checksum(chunk) != (int) checksum.getValue())
+                throw new CorruptBlockException(getPath(), chunk);
+            // reset checksum object back to the original (blank) state
+            checksum.reset();
+        }
+    }
+
     private int checksum(CompressionMetadata.Chunk chunk) throws IOException
     {
         assert channel.position() == chunk.offset + chunk.length;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to