postgres.git / summary / log / commit / refs

commit    3c41f5534aa60402293e7a50c4e44f7d6b6e3e4d
Author:   Heikki Linnakangas <heikki.linnakangas@iki.fi>
Commit:   Noah Misch <noah@leadboat.com>
Date:     Mon May 11 12:13:49 2026 +0000
First released in: 14.23, 15.18, 16.14, 17.10, 18.4

    Fix integer overflow in array_agg(), when the array grows too large
    
    If you accumulate many arrays full of NULLs, you could overflow
    'nitems', before reaching the MaxAllocSize limit on the allocations.
    Add an explicit check that the number of items doesn't grow too large.
    With more than MaxArraySize items, getting the final result with
    makeArrayResultArr() would fail anyway, so better to error out early.
    
    Reported-by: Xint Code
    Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
    Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
    Backpatch-through: 14
    Security: CVE-2026-6473


src/backend/utils/adt/arrayfuncs.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index 41d3a1ba224..75cc4eeca52 100644 --- a/src/backend/utils/adt/arrayfuncs.c +++ b/src/backend/utils/adt/arrayfuncs.c @@ -5555,6 +5555,7 @@ accumArrayResultArr(ArrayBuildStateArr *astate, ndatabytes; char *data; int i; + int newnitems; /* * We disallow accumulating null subarrays. Another plausible definition @@ -5584,6 +5585,14 @@ accumArrayResultArr(ArrayBuildStateArr *astate, nitems = ArrayGetNItems(ndims, dims); ndatabytes = ARR_SIZE(arg) - ARR_DATA_OFFSET(arg); + /* Check that the array doesn't grow too large */ + newnitems = astate->nitems + nitems; + if (newnitems > MaxArraySize) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("array size exceeds the maximum allowed (%zu)", + MaxArraySize))); + if (astate->ndims == 0) { /* First input; check/save the dimensionality info */ @@ -5649,8 +5658,6 @@ accumArrayResultArr(ArrayBuildStateArr *astate, /* Deal with null bitmap if needed */ if (astate->nullbitmap || ARR_HASNULL(arg)) { - int newnitems = astate->nitems + nitems; - if (astate->nullbitmap == NULL) { /* @@ -5674,7 +5681,7 @@ accumArrayResultArr(ArrayBuildStateArr *astate, nitems); } - astate->nitems += nitems; + astate->nitems = newnitems; astate->dims[0] += 1; MemoryContextSwitchTo(oldcontext); [parent: 26dd3cac20ba]