From b89db180bb97debe025b640dc40ed43816e8c7d2 Mon Sep 17 00:00:00 2001 From: Martin Traverso Date: Thu, 8 Feb 2024 10:18:49 -0800 Subject: [PATCH] Fix out of bounds read/write in Snappy decompressor In the slow literal copy path, it wasn't validating that the literal fit within the input buffer, so the call to copyMemory could read from out of bounds and cause a crash. When copying a match, it wasn't validating that the match fit within the output buffer in both branches (slow & fast path), so the operation could write outside of the output buffer if the match length was corrupted. --- .../airlift/compress/snappy/SnappyRawDecompressor.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/airlift/compress/snappy/SnappyRawDecompressor.java b/src/main/java/io/airlift/compress/snappy/SnappyRawDecompressor.java index 6e3e91b1..7cca9afa 100644 --- a/src/main/java/io/airlift/compress/snappy/SnappyRawDecompressor.java +++ b/src/main/java/io/airlift/compress/snappy/SnappyRawDecompressor.java @@ -120,7 +120,7 @@ private static int uncompressAll( // copy literal long literalOutputLimit = output + literalLength; if (literalOutputLimit > fastOutputLimit || input + literalLength > inputLimit - SIZE_OF_LONG) { - if (literalOutputLimit > outputLimit) { + if (literalOutputLimit > outputLimit || input + literalLength > inputLimit) { throw new MalformedInputException(input - inputAddress); } @@ -153,6 +153,9 @@ private static int uncompressAll( throw new MalformedInputException(input - inputAddress); } long matchOutputLimit = output + length; + if (matchOutputLimit > outputLimit) { + throw new MalformedInputException(input - inputAddress); + } if (output > fastOutputLimit) { // slow match copy @@ -185,10 +188,6 @@ private static int uncompressAll( } if (matchOutputLimit > fastOutputLimit) { - if (matchOutputLimit > outputLimit) { - throw new MalformedInputException(input - inputAddress); - } - while (output < fastOutputLimit) { UNSAFE.putLong(outputBase, output, UNSAFE.getLong(outputBase, matchAddress)); matchAddress += SIZE_OF_LONG;