mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-08-03 20:24:14 +02:00
Merge pull request #14740 from acts-1631/security/netplay-lzo-bounds
NetPlay: bound LZO decompression output
This commit is contained in:
@@ -174,7 +174,7 @@ bool CompressBufferIntoPacket(std::span<const u8> in_buffer, sf::Packet& packet)
|
||||
|
||||
bool DecompressPacketIntoFile(sf::Packet& packet, const std::string& file_path)
|
||||
{
|
||||
u64 file_size = Common::PacketReadU64(packet);
|
||||
const u64 file_size = Common::PacketReadU64(packet);
|
||||
|
||||
if (file_size == 0)
|
||||
return true;
|
||||
@@ -188,11 +188,12 @@ bool DecompressPacketIntoFile(sf::Packet& packet, const std::string& file_path)
|
||||
|
||||
std::vector<u8> in_buffer(LZO_OUT_LEN);
|
||||
std::vector<u8> out_buffer(LZO_IN_LEN);
|
||||
u64 bytes_written = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
u32 cur_len = 0; // number of bytes to read
|
||||
lzo_uint new_len = 0; // number of bytes to write
|
||||
u32 cur_len = 0; // number of bytes to read
|
||||
lzo_uint new_len = out_buffer.size(); // output buffer capacity
|
||||
|
||||
packet >> cur_len;
|
||||
if (!cur_len)
|
||||
@@ -209,21 +210,29 @@ bool DecompressPacketIntoFile(sf::Packet& packet, const std::string& file_path)
|
||||
packet >> in_buffer[j];
|
||||
}
|
||||
|
||||
if (lzo1x_decompress(in_buffer.data(), cur_len, out_buffer.data(), &new_len, nullptr) !=
|
||||
if (lzo1x_decompress_safe(in_buffer.data(), cur_len, out_buffer.data(), &new_len, nullptr) !=
|
||||
LZO_E_OK)
|
||||
{
|
||||
PanicAlertFmtT("Internal LZO Error - decompression failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (new_len > file_size - bytes_written)
|
||||
{
|
||||
PanicAlertFmtT("LZO error - output is too large");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file.WriteBytes(out_buffer.data(), new_len))
|
||||
{
|
||||
PanicAlertFmtT("Error writing file: {0}", file_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
bytes_written += new_len;
|
||||
}
|
||||
|
||||
return true;
|
||||
return bytes_written == file_size;
|
||||
}
|
||||
|
||||
static bool DecompressPacketIntoFolderInternal(sf::Packet& packet, const std::string& folder_path)
|
||||
@@ -269,20 +278,21 @@ bool DecompressPacketIntoFolder(sf::Packet& packet, const std::string& folder_pa
|
||||
|
||||
std::optional<std::vector<u8>> DecompressPacketIntoBuffer(sf::Packet& packet)
|
||||
{
|
||||
u64 size = Common::PacketReadU64(packet);
|
||||
const u64 size = Common::PacketReadU64(packet);
|
||||
|
||||
std::vector<u8> out_buffer(size);
|
||||
std::vector<u8> out_buffer;
|
||||
|
||||
if (size == 0)
|
||||
return out_buffer;
|
||||
|
||||
std::vector<u8> in_buffer(LZO_OUT_LEN);
|
||||
std::vector<u8> decompressed_buffer(LZO_IN_LEN);
|
||||
|
||||
lzo_uint i = 0;
|
||||
u64 decompressed_size = 0;
|
||||
while (true)
|
||||
{
|
||||
u32 cur_len = 0; // number of bytes to read
|
||||
lzo_uint new_len = 0; // number of bytes to write
|
||||
u32 cur_len = 0; // number of bytes to read
|
||||
lzo_uint new_len = decompressed_buffer.size(); // output buffer capacity
|
||||
|
||||
packet >> cur_len;
|
||||
if (!cur_len)
|
||||
@@ -299,13 +309,28 @@ std::optional<std::vector<u8>> DecompressPacketIntoBuffer(sf::Packet& packet)
|
||||
packet >> in_buffer[j];
|
||||
}
|
||||
|
||||
if (lzo1x_decompress(in_buffer.data(), cur_len, &out_buffer[i], &new_len, nullptr) != LZO_E_OK)
|
||||
if (lzo1x_decompress_safe(in_buffer.data(), cur_len, decompressed_buffer.data(), &new_len,
|
||||
nullptr) != LZO_E_OK)
|
||||
{
|
||||
PanicAlertFmtT("Internal LZO Error - decompression failed");
|
||||
return {};
|
||||
}
|
||||
|
||||
i += new_len;
|
||||
if (new_len > size - decompressed_size || new_len > out_buffer.max_size() - out_buffer.size())
|
||||
{
|
||||
PanicAlertFmtT("LZO error - output is too large");
|
||||
return {};
|
||||
}
|
||||
|
||||
out_buffer.insert(out_buffer.end(), decompressed_buffer.begin(),
|
||||
decompressed_buffer.begin() + new_len);
|
||||
decompressed_size += new_len;
|
||||
}
|
||||
|
||||
if (decompressed_size != size)
|
||||
{
|
||||
PanicAlertFmtT("LZO error - output size mismatch");
|
||||
return {};
|
||||
}
|
||||
|
||||
return out_buffer;
|
||||
|
||||
Reference in New Issue
Block a user