From f66716f027d876110f59d1ed491de6ec3c9c3912 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 09:48:22 +0000 Subject: [PATCH] fix: validate numChunks, numFlairs, vertSize before resize to prevent OOM from malformed raws Agent-Logs-Url: https://github.com/DarkflameUniverse/DarkflameServer/sessions/39d7ce79-bc9a-4960-8259-f11bcb5947f8 Co-authored-by: aronwk-aaron <26027722+aronwk-aaron@users.noreply.github.com> --- dZoneManager/Raw.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dZoneManager/Raw.cpp b/dZoneManager/Raw.cpp index ed5115c3..14c0b435 100644 --- a/dZoneManager/Raw.cpp +++ b/dZoneManager/Raw.cpp @@ -9,6 +9,7 @@ namespace { constexpr uint32_t kMaxResolution = 4096; constexpr size_t kMaxBlobBytes = 64ULL * 1024 * 1024; // 64 MiB +constexpr uint32_t kMaxChunks = 1024; } // namespace namespace Raw { @@ -220,6 +221,11 @@ namespace Raw { return false; } + const size_t flairBytes = static_cast(numFlairs) * sizeof(FlairAttributes); + if (flairBytes > kMaxBlobBytes) { + LOG("Chunk %u flair count %u exceeds maximum (byte size %zu > %zu)", chunk.id, numFlairs, flairBytes, kMaxBlobBytes); + return false; + } chunk.flairs.resize(numFlairs); for (uint32_t i = 0; i < numFlairs; ++i) { if (!ReadFlairAttributes(stream, chunk.flairs[i])) { @@ -251,6 +257,11 @@ namespace Raw { } // Mesh vert usage + const size_t vertBytes = static_cast(chunk.vertSize) * sizeof(uint16_t); + if (vertBytes > kMaxBlobBytes) { + LOG("Chunk %u vertSize %u exceeds maximum (byte size %zu > %zu)", chunk.id, chunk.vertSize, vertBytes, kMaxBlobBytes); + return false; + } chunk.meshVertUsage.resize(chunk.vertSize); for (uint32_t i = 0; i < chunk.vertSize; ++i) { BinaryIO::BinaryRead(stream, chunk.meshVertUsage[i]); @@ -319,6 +330,11 @@ namespace Raw { BinaryIO::BinaryRead(stream, outRaw.numChunksWidth); BinaryIO::BinaryRead(stream, outRaw.numChunksHeight); + if (outRaw.numChunks > kMaxChunks) { + LOG("Raw numChunks %u exceeds maximum %u", outRaw.numChunks, kMaxChunks); + return false; + } + // Read all chunks outRaw.chunks.resize(outRaw.numChunks); for (uint32_t i = 0; i < outRaw.numChunks; ++i) {