Skip to content

Commit 224f153

Browse files
committed
ORCA: Fix use-after-free in flatten_join_alias_var_optimizer
Guard pfree/list_free calls with pointer-equality checks to avoid freeing live nodes when flatten_join_alias_vars returns the same pointer unchanged (e.g., outer-reference Vars with varlevelsup > 0). The unconditional pfree(havingQual) freed the Var node, whose memory was later reused by palloc for a T_List. copyObjectImpl then copied the wrong node type into havingQual, causing ORCA to encounter an unexpected RangeTblEntry and fall back to the Postgres planner. Applies the same guard pattern to all six fields: targetList, returningList, havingQual, scatterClause, limitOffset, limitCount. Reported-in: #1618
1 parent 021d378 commit 224f153

1 file changed

Lines changed: 13 additions & 7 deletions

File tree

src/backend/optimizer/util/clauses.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5522,35 +5522,40 @@ flatten_join_alias_var_optimizer(Query *query, int queryLevel)
55225522
if (NIL != targetList)
55235523
{
55245524
queryNew->targetList = (List *) flatten_join_alias_vars(queryNew, (Node *) targetList);
5525-
list_free(targetList);
5525+
if (targetList != queryNew->targetList)
5526+
list_free(targetList);
55265527
}
55275528

5528-
List * returningList = queryNew->returningList;
5529+
List *returningList = queryNew->returningList;
55295530
if (NIL != returningList)
55305531
{
55315532
queryNew->returningList = (List *) flatten_join_alias_vars(queryNew, (Node *) returningList);
5532-
list_free(returningList);
5533+
if (returningList != queryNew->returningList)
5534+
list_free(returningList);
55335535
}
55345536

55355537
Node *havingQual = queryNew->havingQual;
55365538
if (NULL != havingQual)
55375539
{
55385540
queryNew->havingQual = flatten_join_alias_vars(queryNew, havingQual);
5539-
pfree(havingQual);
5541+
if (havingQual != queryNew->havingQual)
5542+
pfree(havingQual);
55405543
}
55415544

55425545
List *scatterClause = queryNew->scatterClause;
55435546
if (NIL != scatterClause)
55445547
{
55455548
queryNew->scatterClause = (List *) flatten_join_alias_vars(queryNew, (Node *) scatterClause);
5546-
list_free(scatterClause);
5549+
if (scatterClause != queryNew->scatterClause)
5550+
list_free(scatterClause);
55475551
}
55485552

55495553
Node *limitOffset = queryNew->limitOffset;
55505554
if (NULL != limitOffset)
55515555
{
55525556
queryNew->limitOffset = flatten_join_alias_vars(queryNew, limitOffset);
5553-
pfree(limitOffset);
5557+
if (limitOffset != queryNew->limitOffset)
5558+
pfree(limitOffset);
55545559
}
55555560

55565561
List *windowClause = queryNew->windowClause;
@@ -5577,7 +5582,8 @@ flatten_join_alias_var_optimizer(Query *query, int queryLevel)
55775582
if (NULL != limitCount)
55785583
{
55795584
queryNew->limitCount = flatten_join_alias_vars(queryNew, limitCount);
5580-
pfree(limitCount);
5585+
if (limitCount != queryNew->limitCount)
5586+
pfree(limitCount);
55815587
}
55825588

55835589
return queryNew;

0 commit comments

Comments
 (0)