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

Commit46286d6

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 parent74515dc commit46286d6

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
@@ -29,6 +29,7 @@
2929
#include"parser/parse_func.h"
3030
#include"parser/parse_relation.h"
3131
#include"parser/parse_type.h"
32+
#include"parser/parsetree.h"
3233
#include"utils/builtins.h"
3334
#include"utils/fmgroids.h"
3435
#include"utils/lsyscache.h"
@@ -42,6 +43,7 @@ static Oid **argtype_inherit(int nargs, Oid *argtypes);
4243
staticintfind_inheritors(Oidrelid,Oid**supervec);
4344
staticOid**gen_cross_product(InhPaths*arginh,intnargs);
4445
staticvoidunknown_attribute(ParseState*pstate,Node*relref,char*attname);
46+
staticboolcheck_pg_get_expr_arg(ParseState*pstate,Node*arg,intnetlevelsup);
4547

4648

4749
/*
@@ -1439,9 +1441,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
14391441
void
14401442
check_pg_get_expr_args(ParseState*pstate,Oidfnoid,List*args)
14411443
{
1442-
boolallowed= false;
14431444
Node*arg;
1444-
intnetlevelsup;
14451445

14461446
/* if not being called for pg_get_expr, do nothing */
14471447
if (fnoid!=F_PG_GET_EXPR&&fnoid!=F_PG_GET_EXPR_EXT)
@@ -1453,59 +1453,91 @@ check_pg_get_expr_args(ParseState *pstate, Oid fnoid, List *args)
14531453

14541454
/*
14551455
* The first argument must be a Var referencing one of the allowed
1456-
* system-catalog columns. It could be a join alias Var, though.
1456+
* system-catalog columns. It could be a join alias Var or subquery
1457+
* reference Var, though, so we need a recursive subroutine to chase
1458+
* through those possibilities.
14571459
*/
14581460
Assert(list_length(args)>1);
14591461
arg= (Node*)linitial(args);
1460-
netlevelsup=0;
14611462

1462-
restart:
1463-
if (IsA(arg,Var))
1463+
if (!check_pg_get_expr_arg(pstate,arg,0))
1464+
ereport(ERROR,
1465+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1466+
errmsg("argument to pg_get_expr() must come from system catalogs")));
1467+
}
1468+
1469+
staticbool
1470+
check_pg_get_expr_arg(ParseState*pstate,Node*arg,intnetlevelsup)
1471+
{
1472+
if (arg&&IsA(arg,Var))
14641473
{
14651474
Var*var= (Var*)arg;
14661475
RangeTblEntry*rte;
1476+
AttrNumberattnum;
14671477

14681478
netlevelsup+=var->varlevelsup;
14691479
rte=GetRTEByRangeTablePosn(pstate,var->varno,netlevelsup);
1480+
attnum=var->varattno;
14701481

14711482
if (rte->rtekind==RTE_JOIN)
14721483
{
1473-
/*Expandjoin aliasreference */
1474-
if (var->varattno>0&&
1475-
var->varattno <=list_length(rte->joinaliasvars))
1484+
/*Recursively examinejoin aliasvariable */
1485+
if (attnum>0&&
1486+
attnum <=list_length(rte->joinaliasvars))
14761487
{
1477-
arg= (Node*)list_nth(rte->joinaliasvars,var->varattno-1);
1478-
gotorestart;
1488+
arg= (Node*)list_nth(rte->joinaliasvars,attnum-1);
1489+
returncheck_pg_get_expr_arg(pstate,arg,netlevelsup);
14791490
}
14801491
}
1492+
elseif (rte->rtekind==RTE_SUBQUERY)
1493+
{
1494+
/* Subselect-in-FROM: examine sub-select's output expr */
1495+
TargetEntry*ste=get_tle_by_resno(rte->subquery->targetList,
1496+
attnum);
1497+
ParseStatemypstate;
1498+
1499+
if (ste==NULL||ste->resdom->resjunk)
1500+
elog(ERROR,"subquery %s does not have attribute %d",
1501+
rte->eref->aliasname,attnum);
1502+
arg= (Node*)ste->expr;
1503+
1504+
/*
1505+
* Recurse into the sub-select to see what its expr refers to.
1506+
* We have to build an additional level of ParseState to keep in
1507+
* step with varlevelsup in the subselect.
1508+
*/
1509+
MemSet(&mypstate,0,sizeof(mypstate));
1510+
mypstate.parentParseState=pstate;
1511+
mypstate.p_rtable=rte->subquery->rtable;
1512+
/* don't bother filling the rest of the fake pstate */
1513+
1514+
returncheck_pg_get_expr_arg(&mypstate,arg,0);
1515+
}
14811516
elseif (rte->rtekind==RTE_RELATION)
14821517
{
14831518
if (rte->relid==get_system_catalog_relid(IndexRelationName))
14841519
{
1485-
if (var->varattno==Anum_pg_index_indexprs||
1486-
var->varattno==Anum_pg_index_indpred)
1487-
allowed= true;
1520+
if (attnum==Anum_pg_index_indexprs||
1521+
attnum==Anum_pg_index_indpred)
1522+
return true;
14881523
}
14891524
elseif (rte->relid==get_system_catalog_relid(AttrDefaultRelationName))
14901525
{
1491-
if (var->varattno==Anum_pg_attrdef_adbin)
1492-
allowed= true;
1526+
if (attnum==Anum_pg_attrdef_adbin)
1527+
return true;
14931528
}
14941529
elseif (rte->relid==get_system_catalog_relid(ConstraintRelationName))
14951530
{
1496-
if (var->varattno==Anum_pg_constraint_conbin)
1497-
allowed= true;
1531+
if (attnum==Anum_pg_constraint_conbin)
1532+
return true;
14981533
}
14991534
elseif (rte->relid==get_system_catalog_relid(TypeRelationName))
15001535
{
1501-
if (var->varattno==Anum_pg_type_typdefaultbin)
1502-
allowed= true;
1536+
if (attnum==Anum_pg_type_typdefaultbin)
1537+
return true;
15031538
}
15041539
}
15051540
}
15061541

1507-
if (!allowed)
1508-
ereport(ERROR,
1509-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1510-
errmsg("argument to pg_get_expr() must come from system catalogs")));
1542+
return false;
15111543
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp