Merge pull request #9028 from Enmk/Gorilla_and_DoubleDelta_buffer_overflow_fix

Fixed buffer overflow on decoding small sequences with Gorilla and DoubleDelta
This commit is contained in:
alesapin 2020-02-07 11:40:08 +03:00 committed by GitHub
commit f4467aaa65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 25 deletions

View File

@ -241,30 +241,35 @@ void decompressDataForType(const char * source, UInt32 source_size, char * dest)
const char * source_end = source + source_size;
if (source + sizeof(UInt32) > source_end)
return;
const UInt32 items_count = unalignedLoad<UInt32>(source);
source += sizeof(items_count);
ValueType prev_value{};
UnsignedDeltaType prev_delta{};
if (source < source_end)
{
// decoding first item
if (source + sizeof(ValueType) > source_end || items_count < 1)
return;
prev_value = unalignedLoad<ValueType>(source);
unalignedStore<ValueType>(dest, prev_value);
source += sizeof(prev_value);
dest += sizeof(prev_value);
}
if (source < source_end)
{
// decoding second item
if (source + sizeof(UnsignedDeltaType) > source_end || items_count < 2)
return;
prev_delta = unalignedLoad<UnsignedDeltaType>(source);
prev_value = prev_value + static_cast<ValueType>(prev_delta);
unalignedStore<ValueType>(dest, prev_value);
source += sizeof(prev_delta);
dest += sizeof(prev_value);
}
BitReader reader(source, source_size - sizeof(prev_value) - sizeof(prev_delta) - sizeof(items_count));

View File

@ -159,19 +159,23 @@ void decompressDataForType(const char * source, UInt32 source_size, char * dest)
const char * source_end = source + source_size;
if (source + sizeof(UInt32) > source_end)
return;
const UInt32 items_count = unalignedLoad<UInt32>(source);
source += sizeof(items_count);
T prev_value{};
if (source < source_end)
{
// decoding first item
if (source + sizeof(T) > source_end || items_count < 1)
return;
prev_value = unalignedLoad<T>(source);
unalignedStore<T>(dest, prev_value);
source += sizeof(prev_value);
dest += sizeof(prev_value);
}
BitReader reader(source, source_size - sizeof(items_count) - sizeof(prev_value));

View File

@ -158,8 +158,8 @@ public:
explicit BinaryDataAsSequenceOfValuesIterator(const Container & container_)
: container(container_),
data(&container[0]),
data_end(reinterpret_cast<const char *>(data) + container.size()),
data(container.data()),
data_end(container.data() + container.size()),
current_value(T{})
{
static_assert(sizeof(container[0]) == 1 && std::is_pod<std::decay_t<decltype(container[0])>>::value, "Only works on containers of byte-size PODs.");
@ -789,12 +789,14 @@ auto FFand0Generator = []()
};
// Makes many sequences with generator, first sequence length is 1, second is 2... up to `sequences_count`.
// Makes many sequences with generator, first sequence length is 0, second is 1..., third is 2 up to `sequences_count`.
template <typename T, typename Generator>
std::vector<CodecTestSequence> generatePyramidOfSequences(const size_t sequences_count, Generator && generator, const char* generator_name)
{
std::vector<CodecTestSequence> sequences;
sequences.reserve(sequences_count);
sequences.push_back(makeSeq<T>()); // sequence of size 0
for (size_t i = 1; i < sequences_count; ++i)
{
std::string name = generator_name + std::string(" from 0 to ") + std::to_string(i);