This is an automated email from the ASF dual-hosted git repository. yjhjstz pushed a commit to branch yjhjstz/fix/orca-use-after-free-having-decorrelation in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 77d365c6f531abf7106e8ac3a7836712f86afb8a Author: Jianghua Yang <[email protected]> AuthorDate: Sat Mar 14 03:50:51 2026 +0800 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: https://github.com/apache/cloudberry/issues/1618 --- src/backend/optimizer/util/clauses.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 2669f2c3017..9085f3876a4 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -5522,35 +5522,40 @@ flatten_join_alias_var_optimizer(Query *query, int queryLevel) if (NIL != targetList) { queryNew->targetList = (List *) flatten_join_alias_vars(queryNew, (Node *) targetList); - list_free(targetList); + if (targetList != queryNew->targetList) + list_free(targetList); } - List * returningList = queryNew->returningList; + List *returningList = queryNew->returningList; if (NIL != returningList) { queryNew->returningList = (List *) flatten_join_alias_vars(queryNew, (Node *) returningList); - list_free(returningList); + if (returningList != queryNew->returningList) + list_free(returningList); } Node *havingQual = queryNew->havingQual; if (NULL != havingQual) { queryNew->havingQual = flatten_join_alias_vars(queryNew, havingQual); - pfree(havingQual); + if (havingQual != queryNew->havingQual) + pfree(havingQual); } List *scatterClause = queryNew->scatterClause; if (NIL != scatterClause) { queryNew->scatterClause = (List *) flatten_join_alias_vars(queryNew, (Node *) scatterClause); - list_free(scatterClause); + if (scatterClause != queryNew->scatterClause) + list_free(scatterClause); } Node *limitOffset = queryNew->limitOffset; if (NULL != limitOffset) { queryNew->limitOffset = flatten_join_alias_vars(queryNew, limitOffset); - pfree(limitOffset); + if (limitOffset != queryNew->limitOffset) + pfree(limitOffset); } List *windowClause = queryNew->windowClause; @@ -5577,7 +5582,8 @@ flatten_join_alias_var_optimizer(Query *query, int queryLevel) if (NULL != limitCount) { queryNew->limitCount = flatten_join_alias_vars(queryNew, limitCount); - pfree(limitCount); + if (limitCount != queryNew->limitCount) + pfree(limitCount); } return queryNew; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
