Re: BUG #17858: ExecEvalArrayExpr() leaves uninitialised memory for multidim array with nulls - Mailing list pgsql-bugs

From Richard Guo
Subject Re: BUG #17858: ExecEvalArrayExpr() leaves uninitialised memory for multidim array with nulls
Date
Msg-id CAMbWs48CyDghUckGQbkbAB6uPdfzYS4X4Zkdfooausr5vaV9Bg@mail.gmail.com
Whole thread Raw
In response to BUG #17858: ExecEvalArrayExpr() leaves uninitialised memory for multidim array with nulls  (PG Bug reporting form <noreply@postgresql.org>)
Responses Re: BUG #17858: ExecEvalArrayExpr() leaves uninitialised memory for multidim array with nulls
List pgsql-bugs

On Tue, Mar 21, 2023 at 5:32 PM PG Bug reporting form <noreply@postgresql.org> wrote:
With a server compiled with flags -DUSE_VALGRIND
-DWRITE_READ_PARSE_PLAN_TREES the following query:
SELECT * FROM generate_series(1, 1) a WHERE a = ANY
(array[array[NULL::int]]);

provokes an incorrect memory access:

Here ExecEvalArrayExpr() performs:
                result = (ArrayType *) palloc(nbytes);
where nbytes includes ARR_OVERHEAD_WITHNULLS(ndims, nitems) for ndims = 2
and nitems = 1, so last 8 bytes in this memory area reserved for a null
bitmap, but only one bit of the bitmap initialised later by
array_bitmap_copy().

Something like:
@@ -2860,6 +2861,9 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep
*op)
                result->elemtype = element_type;
                memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
                memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
+               nullbitmap = ARR_NULLBITMAP(result);
+               if (nullbitmap)
+                       memset(nullbitmap, 0, ARR_OVERHEAD_WITHNULLS(ndims,
nitems) - ARR_OVERHEAD_NONULLS(ndims));

                dat = ARR_DATA_PTR(result);
                iitem = 0;

fixes the issue, just as "result = (ArrayType *) palloc0(nbytes)" does, of
course.

Nice catch.  This can also be seen on master.

I searched the codes a little bit and found that in array_set_slice()
and array_set_element() the 'newarray' is allocated with palloc0 and
then the nulls bitmap is zeroed with

 MemSet(nullbitmap, 0, (nitems + 7) / 8);

if havenulls is true.  I wonder if we can do the same here.

Thanks
Richard

pgsql-bugs by date:

Previous
From: PG Bug reporting form
Date:
Subject: BUG #17859: Suspected collation conflict when using recursive query
Next
From: Tianyi Gao
Date:
Subject: operator class "xxx" does not exist for access method "yyy"