Skip to content

Commit 30caa67

Browse files
Affan KhanCopilot
andcommitted
Fix std::bad_alloc in C++ blob API with oversized map/array counts
The fuzz_blob_corpus runner crashed on the new overflow corpus files because the C++ Blob API (merge_patch, each_iter, tree_walk) attempted to allocate vectors sized by the raw MAP32/ARRAY32 count without first checking whether that count is plausible given the available data. Added sanity checks before vector allocations and loops that reject element counts exceeding the remaining data capacity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2466005 commit 30caa67

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

‎src/msgpack_blob.cpp‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,8 @@ static int merge_patch(
972972
uint32_t keyOff, valOff, pairEnd;
973973
bool matched;
974974
};
975+
/* Sanity: each map pair needs at least 2 bytes; reject implausible counts */
976+
if (pCount > (np - pDataOff) / 2 + 1) return RC_ERROR;
975977
std::vector<PatchEntry> pIdx(pCount);
976978
{
977979
uint32_t pc2 = pDataOff;
@@ -1458,6 +1460,12 @@ static void each_iter(
14581460
else if (b == MP_MAP32 && iCont + 5 <= n) { isMap = true; count = read32(a + iCont + 1); dataOff = iCont + 5; }
14591461

14601462
if (!isArr && !isMap) return;
1463+
1464+
/* Sanity: reject counts that exceed remaining data capacity */
1465+
uint32_t remaining = (dataOff <= n) ? (n - dataOff) : 0;
1466+
uint32_t minBytesPerElem = isMap ? 2u : 1u;
1467+
if (count > remaining / minBytesPerElem + 1) return;
1468+
14611469
uint32_t cur = dataOff;
14621470

14631471
for (uint32_t j = 0; j < count; j++) {
@@ -1532,6 +1540,12 @@ static void tree_walk(
15321540
else if (b == MP_MAP32 && iOff + 5 <= n) { isMap = true; count = read32(a + iOff + 1); dataOff = iOff + 5; }
15331541

15341542
if (!isArr && !isMap) return;
1543+
1544+
/* Sanity: reject counts that exceed remaining data capacity */
1545+
uint32_t tRemaining = (dataOff <= n) ? (n - dataOff) : 0;
1546+
uint32_t tMinBytes = isMap ? 2u : 1u;
1547+
if (count > tRemaining / tMinBytes + 1) return;
1548+
15351549
uint32_t cur = dataOff;
15361550

15371551
for (uint32_t j = 0; j < count; j++) {

0 commit comments

Comments
 (0)