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

From PG Bug reporting form
Subject BUG #17858: ExecEvalArrayExpr() leaves uninitialised memory for multidim array with nulls
Date
Msg-id 17858-8fd287fd3663d051@postgresql.org
Whole thread Raw
Responses Re: BUG #17858: ExecEvalArrayExpr() leaves uninitialised memory for multidim array with nulls
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      17858
Logged by:          Alexander Lakhin
Email address:      exclusion@gmail.com
PostgreSQL version: 15.2
Operating system:   Ubuntu 22.04
Description:

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:
==00:00:00:06.362 433114== Conditional jump or move depends on uninitialised
value(s)
==00:00:00:06.362 433114==    at 0x76EF57: adjust_sign (snprintf.c:1483)
==00:00:00:06.362 433114==    by 0x76F404: fmtint (snprintf.c:1072)
==00:00:00:06.362 433114==    by 0x7700CD: dopr (snprintf.c:623)
==00:00:00:06.362 433114==    by 0x770509: pg_vsnprintf (snprintf.c:205)
==00:00:00:06.362 433114==    by 0x76612C: pvsnprintf (psprintf.c:110)
==00:00:00:06.362 433114==    by 0x7675FC: appendStringInfoVA
(stringinfo.c:149)
==00:00:00:06.362 433114==    by 0x767815: appendStringInfo
(stringinfo.c:103)
==00:00:00:06.362 433114==    by 0x4836BC: outDatum (outfuncs.c:298)
==00:00:00:06.362 433114==    by 0x4837F4: _outConst (outfuncs.c:1169)
==00:00:00:06.362 433114==    by 0x483C6E: outNode (outfuncs.c:4088)
==00:00:00:06.362 433114==    by 0x484787: _outList (outfuncs.c:234)
==00:00:00:06.362 433114==    by 0x483856: outNode (outfuncs.c:3896)
==00:00:00:06.362 433114==    by 0x488285: _outScalarArrayOpExpr
(outfuncs.c:1339)
==00:00:00:06.362 433114==    by 0x483D1E: outNode (outfuncs.c:4121)
==00:00:00:06.362 433114==    by 0x484787: _outList (outfuncs.c:234)
==00:00:00:06.362 433114==    by 0x483856: outNode (outfuncs.c:3896)
==00:00:00:06.362 433114==    by 0x484CCB: _outPlanInfo (outfuncs.c:353)
==00:00:00:06.362 433114==    by 0x485187: _outScanInfo (outfuncs.c:367)
==00:00:00:06.362 433114==    by 0x486235: _outFunctionScan
(outfuncs.c:656)
==00:00:00:06.362 433114==    by 0x483A2E: outNode (outfuncs.c:3980)
==00:00:00:06.362 433114==    by 0x484A19: _outPlannedStmt
(outfuncs.c:323)
==00:00:00:06.362 433114==    by 0x4838D9: outNode (outfuncs.c:3914)
==00:00:00:06.362 433114==    by 0x4908A5: nodeToString (outfuncs.c:4617)
==00:00:00:06.362 433114==    by 0x5C312E: pg_plan_query (postgres.c:913)
==00:00:00:06.362 433114==    by 0x5C31F5: pg_plan_queries
(postgres.c:975)
==00:00:00:06.362 433114==    by 0x5C36EA: exec_simple_query
(postgres.c:1169)
==00:00:00:06.362 433114==    by 0x5C566F: PostgresMain (postgres.c:4593)
==00:00:00:06.362 433114==    by 0x51F934: BackendRun (postmaster.c:4511)
==00:00:00:06.362 433114==    by 0x522A06: BackendStartup
(postmaster.c:4239)
==00:00:00:06.362 433114==    by 0x522C3F: ServerLoop (postmaster.c:1806)
==00:00:00:06.362 433114==    by 0x52420E: PostmasterMain
(postmaster.c:1478)
==00:00:00:06.362 433114==    by 0x467CB6: main (main.c:202)
==00:00:00:06.362 433114==  Uninitialised value was created by a heap
allocation
==00:00:00:06.362 433114==    at 0x74411F: palloc (mcxt.c:1093)
==00:00:00:06.362 433114==    by 0x3FECDB: ExecEvalArrayExpr
(execExprInterp.c:2856)
==00:00:00:06.362 433114==    by 0x402183: ExecInterpExpr
(execExprInterp.c:1335)
==00:00:00:06.362 433114==    by 0x3FE16A: ExecInterpExprStillValid
(execExprInterp.c:1826)
==00:00:00:06.362 433114==    by 0x4F00D4: ExecEvalExprSwitchContext
(executor.h:341)
==00:00:00:06.362 433114==    by 0x4F00D4: evaluate_expr (clauses.c:4823)
==00:00:00:06.362 433114==    by 0x4F1236: eval_const_expressions_mutator
(clauses.c:3098)
==00:00:00:06.362 433114==    by 0x480FFB: expression_tree_mutator
(nodeFuncs.c:3166)
==00:00:00:06.362 433114==    by 0x4F19AE: eval_const_expressions_mutator
(clauses.c:3527)
==00:00:00:06.362 433114==    by 0x4807B8: expression_tree_mutator
(nodeFuncs.c:2830)
==00:00:00:06.362 433114==    by 0x4F0971: eval_const_expressions_mutator
(clauses.c:2653)
==00:00:00:06.362 433114==    by 0x4F1B29: eval_const_expressions
(clauses.c:2107)
==00:00:00:06.362 433114==    by 0x4D0475: preprocess_expression
(planner.c:1127)
==00:00:00:06.362 433114==    by 0x4D058F: preprocess_qual_conditions
(planner.c:1199)
==00:00:00:06.362 433114==    by 0x4D918E: subquery_planner
(planner.c:815)
==00:00:00:06.362 433114==    by 0x4D9D14: standard_planner
(planner.c:406)
==00:00:00:06.362 433114==    by 0x4DA2C9: planner (planner.c:277)
==00:00:00:06.362 433114==    by 0x5C311A: pg_plan_query (postgres.c:883)
==00:00:00:06.362 433114==    by 0x5C31F5: pg_plan_queries
(postgres.c:975)
==00:00:00:06.362 433114==    by 0x5C36EA: exec_simple_query
(postgres.c:1169)
==00:00:00:06.362 433114==    by 0x5C566F: PostgresMain (postgres.c:4593)
==00:00:00:06.362 433114==    by 0x51F934: BackendRun (postmaster.c:4511)
==00:00:00:06.362 433114==    by 0x522A06: BackendStartup
(postmaster.c:4239)
==00:00:00:06.362 433114==    by 0x522C3F: ServerLoop (postmaster.c:1806)
==00:00:00:06.362 433114==    by 0x52420E: PostmasterMain
(postmaster.c:1478)
==00:00:00:06.362 433114==    by 0x467CB6: main (main.c:202)
==00:00:00:06.362 433114==

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.


pgsql-bugs by date:

Previous
From: Richard Guo
Date:
Subject: Re: Clause accidentally pushed down ( Possible bug in Making Vars outer-join aware)
Next
From: PG Bug reporting form
Date:
Subject: BUG #17859: Suspected collation conflict when using recursive query