mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Detect CVE-2021-3520 when decompressing using LZ4
This commit is contained in:
@@ -65,26 +65,33 @@ lz4Compress(void const* in, std::size_t inSize, BufferFactory&& bf)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param in Compressed data
|
* @param in Compressed data
|
||||||
* @param inSize Size of compressed data
|
* @param inSizeUnchecked Size of compressed data
|
||||||
* @param decompressed Buffer to hold decompressed data
|
* @param decompressed Buffer to hold decompressed data
|
||||||
* @param decompressedSize Size of the decompressed buffer
|
* @param decompressedSizeUnchecked Size of the decompressed buffer
|
||||||
* @return size of the decompressed data
|
* @return size of the decompressed data
|
||||||
*/
|
*/
|
||||||
inline std::size_t
|
inline std::size_t
|
||||||
lz4Decompress(
|
lz4Decompress(
|
||||||
std::uint8_t const* in,
|
std::uint8_t const* in,
|
||||||
std::size_t inSize,
|
std::size_t inSizeUnchecked,
|
||||||
std::uint8_t* decompressed,
|
std::uint8_t* decompressed,
|
||||||
std::size_t decompressedSize)
|
std::size_t decompressedSizeUnchecked)
|
||||||
{
|
{
|
||||||
auto ret = LZ4_decompress_safe(
|
int const inSize = static_cast<int>(inSizeUnchecked);
|
||||||
reinterpret_cast<const char*>(in),
|
int const decompressedSize = static_cast<int>(decompressedSizeUnchecked);
|
||||||
reinterpret_cast<char*>(decompressed),
|
|
||||||
inSize,
|
|
||||||
decompressedSize);
|
|
||||||
|
|
||||||
if (ret <= 0 || ret != decompressedSize)
|
if (inSize <= 0)
|
||||||
Throw<std::runtime_error>("lz4 decompress: failed");
|
Throw<std::runtime_error>("lz4Decompress: integer overflow (input)");
|
||||||
|
|
||||||
|
if (decompressedSize <= 0)
|
||||||
|
Throw<std::runtime_error>("lz4Decompress: integer overflow (output)");
|
||||||
|
|
||||||
|
if (LZ4_decompress_safe(
|
||||||
|
reinterpret_cast<const char*>(in),
|
||||||
|
reinterpret_cast<char*>(decompressed),
|
||||||
|
inSize,
|
||||||
|
decompressedSize) != decompressedSize)
|
||||||
|
Throw<std::runtime_error>("lz4Decompress: failed");
|
||||||
|
|
||||||
return decompressedSize;
|
return decompressedSize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,22 +42,30 @@ template <class BufferFactory>
|
|||||||
std::pair<void const*, std::size_t>
|
std::pair<void const*, std::size_t>
|
||||||
lz4_decompress(void const* in, std::size_t in_size, BufferFactory&& bf)
|
lz4_decompress(void const* in, std::size_t in_size, BufferFactory&& bf)
|
||||||
{
|
{
|
||||||
using std::runtime_error;
|
if (static_cast<int>(in_size) < 0)
|
||||||
using namespace nudb::detail;
|
Throw<std::runtime_error>("lz4_decompress: integer overflow (input)");
|
||||||
std::pair<void const*, std::size_t> result;
|
|
||||||
std::uint8_t const* p = reinterpret_cast<std::uint8_t const*>(in);
|
std::size_t outSize = 0;
|
||||||
auto const n = read_varint(p, in_size, result.second);
|
|
||||||
if (n == 0)
|
auto const n = read_varint(
|
||||||
Throw<std::runtime_error>("lz4 decompress: n == 0");
|
reinterpret_cast<std::uint8_t const*>(in), in_size, outSize);
|
||||||
void* const out = bf(result.second);
|
|
||||||
result.first = out;
|
if (n == 0 || n >= in_size)
|
||||||
|
Throw<std::runtime_error>("lz4_decompress: invalid blob");
|
||||||
|
|
||||||
|
if (static_cast<int>(outSize) <= 0)
|
||||||
|
Throw<std::runtime_error>("lz4_decompress: integer overflow (output)");
|
||||||
|
|
||||||
|
void* const out = bf(outSize);
|
||||||
|
|
||||||
if (LZ4_decompress_safe(
|
if (LZ4_decompress_safe(
|
||||||
reinterpret_cast<char const*>(in) + n,
|
reinterpret_cast<char const*>(in) + n,
|
||||||
reinterpret_cast<char*>(out),
|
reinterpret_cast<char*>(out),
|
||||||
in_size - n,
|
static_cast<int>(in_size - n),
|
||||||
result.second) != result.second)
|
static_cast<int>(outSize)) != static_cast<int>(outSize))
|
||||||
Throw<std::runtime_error>("lz4 decompress: LZ4_decompress_safe");
|
Throw<std::runtime_error>("lz4_decompress: LZ4_decompress_safe");
|
||||||
return result;
|
|
||||||
|
return {out, outSize};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class BufferFactory>
|
template <class BufferFactory>
|
||||||
|
|||||||
Reference in New Issue
Block a user