]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix integer overflow in array_agg(), when the array grows too large
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 11 May 2026 12:13:51 +0000 (05:13 -0700)
committerNoah Misch <noah@leadboat.com>
Mon, 11 May 2026 12:13:51 +0000 (05:13 -0700)
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

index 3493a5374a19566b5eab1c4603b74b7dfa5f7e3a..1047b48eb70adb556c384ad40de687b8f53ddb96 100644 (file)
@@ -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);