diff --git a/3rdParty/rocksdb/6.0.fb/env/env_encryption.cc b/3rdParty/rocksdb/6.0.fb/env/env_encryption.cc index 1f2bfa7e52..aa59e66357 100644 --- a/3rdParty/rocksdb/6.0.fb/env/env_encryption.cc +++ b/3rdParty/rocksdb/6.0.fb/env/env_encryption.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include "rocksdb/env_encryption.h" #include "util/aligned_buffer.h" @@ -733,6 +734,8 @@ Status BlockAccessCipherStream::Decrypt(uint64_t fileOffset, char *data, size_t std::string scratch; AllocateScratch(scratch); + assert(fileOffset < dataSize); + // Decrypt individual blocks. while (1) { char *block = data; @@ -756,6 +759,14 @@ Status BlockAccessCipherStream::Decrypt(uint64_t fileOffset, char *data, size_t // Copy decrypted data back to `data`. memmove(data, block + blockOffset, n); } + + // Simply decrementing dataSize by n could cause it to underflow, + // which will very likely make it read over the original bounds later + assert(dataSize >= n); + if (dataSize < n) { + return Status::Corruption("Cannot decrypt data at given offset"); + } + dataSize -= n; if (dataSize == 0) { return Status::OK(); @@ -882,6 +893,13 @@ Status CTREncryptionProvider::CreateCipherStream( Slice iv; decodeCTRParameters(prefix.data(), blockSize, initialCounter, iv); + // If the prefix is smaller than twice the block size, we would below read a + // very large chunk of the file (and very likely read over the bounds) + assert(prefix.size() >= 2 * blockSize); + if (prefix.size() < 2 * blockSize) { + return Status::Corruption("Unable to read from file " + fname + ": read attempt would read beyond file bounds"); + } + // Decrypt the encrypted part of the prefix, starting from block 2 (block 0, 1 with initial counter & IV are unencrypted) CTRCipherStream cipherStream(cipher_, iv.data(), initialCounter); auto status = cipherStream.Decrypt(0, (char*)prefix.data() + (2 * blockSize), prefix.size() - (2 * blockSize)); diff --git a/arangod/RocksDBEngine/RocksDBEngine.cpp b/arangod/RocksDBEngine/RocksDBEngine.cpp index 318e348542..93c814e3de 100644 --- a/arangod/RocksDBEngine/RocksDBEngine.cpp +++ b/arangod/RocksDBEngine/RocksDBEngine.cpp @@ -102,7 +102,7 @@ using namespace arangodb::application_features; using namespace arangodb::options; namespace arangodb { - + std::string const RocksDBEngine::EngineName("rocksdb"); std::string const RocksDBEngine::FeatureName("RocksDBEngine"); diff --git a/arangod/RocksDBEngine/RocksDBEngine.h b/arangod/RocksDBEngine/RocksDBEngine.h index f2fb135182..30a257daea 100644 --- a/arangod/RocksDBEngine/RocksDBEngine.h +++ b/arangod/RocksDBEngine/RocksDBEngine.h @@ -346,6 +346,7 @@ class RocksDBEngine final : public StorageEngine { void prepareEnterprise(); void startEnterprise(); void configureEnterpriseRocksDBOptions(rocksdb::Options& options); + void validateJournalFiles() const; enterprise::RocksDBEngineEEData _eeData; #endif