postgres.git / summary / log / commit / refs

commit    e49e9590d984d60bfd95b438e5c6c07d08e9d661
Author:   Heikki Linnakangas <heikki.linnakangas@iki.fi>
Commit:   Noah Misch <noah@leadboat.com>
Date:     Mon May 11 12:13:51 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 3493a5374a1..1047b48eb70 100644 --- a/src/backend/utils/adt/arrayfuncs.c +++ b/src/backend/utils/adt/arrayfuncs.c @@ -5543,6 +5543,7 @@ accumArrayResultArr(ArrayBuildStateArr *astate, ndatabytes; char *data; int i; + int newnitems; /* * We disallow accumulating null subarrays. Another plausible definition @@ -5572,6 +5573,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 */ @@ -5637,8 +5646,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) { /* @@ -5662,7 +5669,7 @@ accumArrayResultArr(ArrayBuildStateArr *astate, nitems); } - astate->nitems += nitems; + astate->nitems = newnitems; astate->dims[0] += 1; MemoryContextSwitchTo(oldcontext); [parent: fb0bc321d3a9]