Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit42c3871

Browse files
committed
Further fixes to the pg_get_expr() security fix in back branches.
It now emerges that the JDBC driver expects to be able to use pg_get_expr()on an output of a sub-SELECT. So extend the check logic to be able to recurseinto a sub-SELECT to see if the argument is ultimately coming from anappropriate column. Per report from Thomas Kellerer.
1 parentdbf859c commit42c3871

File tree

1 file changed

+56
-24
lines changed

1 file changed

+56
-24
lines changed

‎src/backend/parser/parse_func.c

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include"parser/parse_func.h"
3131
#include"parser/parse_relation.h"
3232
#include"parser/parse_type.h"
33+
#include"parser/parsetree.h"
3334
#include"utils/builtins.h"
3435
#include"utils/fmgroids.h"
3536
#include"utils/lsyscache.h"
@@ -44,6 +45,7 @@ static Oid **gen_cross_product(InhPaths *arginh, int nargs);
4445
staticFieldSelect*setup_field_select(Node*input,char*attname,Oidrelid);
4546
staticvoidunknown_attribute(constchar*schemaname,constchar*relname,
4647
constchar*attname);
48+
staticboolcheck_pg_get_expr_arg(ParseState*pstate,Node*arg,intnetlevelsup);
4749

4850

4951
/*
@@ -1584,9 +1586,7 @@ GetRTEByRangeTablePosn(ParseState *pstate,
15841586
void
15851587
check_pg_get_expr_args(ParseState*pstate,Oidfnoid,List*args)
15861588
{
1587-
boolallowed= false;
15881589
Node*arg;
1589-
intnetlevelsup;
15901590

15911591
/* if not being called for pg_get_expr, do nothing */
15921592
if (fnoid!=F_PG_GET_EXPR&&fnoid!=F_PG_GET_EXPR_EXT)
@@ -1598,59 +1598,91 @@ check_pg_get_expr_args(ParseState *pstate, Oid fnoid, List *args)
15981598

15991599
/*
16001600
* The first argument must be a Var referencing one of the allowed
1601-
* system-catalog columns. It could be a join alias Var, though.
1601+
* system-catalog columns. It could be a join alias Var or subquery
1602+
* reference Var, though, so we need a recursive subroutine to chase
1603+
* through those possibilities.
16021604
*/
16031605
Assert(args!=NIL);
16041606
arg= (Node*)lfirst(args);
1605-
netlevelsup=0;
16061607

1607-
restart:
1608-
if (IsA(arg,Var))
1608+
if (!check_pg_get_expr_arg(pstate,arg,0))
1609+
ereport(ERROR,
1610+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1611+
errmsg("argument to pg_get_expr() must come from system catalogs")));
1612+
}
1613+
1614+
staticbool
1615+
check_pg_get_expr_arg(ParseState*pstate,Node*arg,intnetlevelsup)
1616+
{
1617+
if (arg&&IsA(arg,Var))
16091618
{
16101619
Var*var= (Var*)arg;
16111620
RangeTblEntry*rte;
1621+
AttrNumberattnum;
16121622

16131623
netlevelsup+=var->varlevelsup;
16141624
rte=GetRTEByRangeTablePosn(pstate,var->varno,netlevelsup);
1625+
attnum=var->varattno;
16151626

16161627
if (rte->rtekind==RTE_JOIN)
16171628
{
1618-
/*Expandjoin aliasreference */
1619-
if (var->varattno>0&&
1620-
var->varattno <=length(rte->joinaliasvars))
1629+
/*Recursively examinejoin aliasvariable */
1630+
if (attnum>0&&
1631+
attnum <=length(rte->joinaliasvars))
16211632
{
1622-
arg= (Node*)nth(var->varattno-1,rte->joinaliasvars);
1623-
gotorestart;
1633+
arg= (Node*)nth(attnum-1,rte->joinaliasvars);
1634+
returncheck_pg_get_expr_arg(pstate,arg,netlevelsup);
16241635
}
16251636
}
1637+
elseif (rte->rtekind==RTE_SUBQUERY)
1638+
{
1639+
/* Subselect-in-FROM: examine sub-select's output expr */
1640+
TargetEntry*ste=get_tle_by_resno(rte->subquery->targetList,
1641+
attnum);
1642+
ParseStatemypstate;
1643+
1644+
if (ste==NULL||ste->resdom->resjunk)
1645+
elog(ERROR,"subquery %s does not have attribute %d",
1646+
rte->eref->aliasname,attnum);
1647+
arg= (Node*)ste->expr;
1648+
1649+
/*
1650+
* Recurse into the sub-select to see what its expr refers to.
1651+
* We have to build an additional level of ParseState to keep in
1652+
* step with varlevelsup in the subselect.
1653+
*/
1654+
MemSet(&mypstate,0,sizeof(mypstate));
1655+
mypstate.parentParseState=pstate;
1656+
mypstate.p_rtable=rte->subquery->rtable;
1657+
/* don't bother filling the rest of the fake pstate */
1658+
1659+
returncheck_pg_get_expr_arg(&mypstate,arg,0);
1660+
}
16261661
elseif (rte->rtekind==RTE_RELATION)
16271662
{
16281663
if (rte->relid==get_system_catalog_relid(IndexRelationName))
16291664
{
1630-
if (var->varattno==Anum_pg_index_indexprs||
1631-
var->varattno==Anum_pg_index_indpred)
1632-
allowed= true;
1665+
if (attnum==Anum_pg_index_indexprs||
1666+
attnum==Anum_pg_index_indpred)
1667+
return true;
16331668
}
16341669
elseif (rte->relid==get_system_catalog_relid(AttrDefaultRelationName))
16351670
{
1636-
if (var->varattno==Anum_pg_attrdef_adbin)
1637-
allowed= true;
1671+
if (attnum==Anum_pg_attrdef_adbin)
1672+
return true;
16381673
}
16391674
elseif (rte->relid==get_system_catalog_relid(ConstraintRelationName))
16401675
{
1641-
if (var->varattno==Anum_pg_constraint_conbin)
1642-
allowed= true;
1676+
if (attnum==Anum_pg_constraint_conbin)
1677+
return true;
16431678
}
16441679
elseif (rte->relid==get_system_catalog_relid(TypeRelationName))
16451680
{
1646-
if (var->varattno==Anum_pg_type_typdefaultbin)
1647-
allowed= true;
1681+
if (attnum==Anum_pg_type_typdefaultbin)
1682+
return true;
16481683
}
16491684
}
16501685
}
16511686

1652-
if (!allowed)
1653-
ereport(ERROR,
1654-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1655-
errmsg("argument to pg_get_expr() must come from system catalogs")));
1687+
return false;
16561688
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp