|
8 | 8 | * |
9 | 9 | * |
10 | 10 | * IDENTIFICATION |
11 | | - * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.226 2010/08/05 21:45:35 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.227 2010/09/03 01:26:52 tgl Exp $ |
12 | 12 | * |
13 | 13 | *------------------------------------------------------------------------- |
14 | 14 | */ |
15 | 15 | #include"postgres.h" |
16 | 16 |
|
17 | | -#include"catalog/pg_attrdef.h" |
18 | | -#include"catalog/pg_constraint.h" |
19 | 17 | #include"catalog/pg_proc.h" |
20 | 18 | #include"catalog/pg_type.h" |
21 | 19 | #include"funcapi.h" |
22 | | -#include"miscadmin.h" |
23 | 20 | #include"nodes/makefuncs.h" |
24 | 21 | #include"nodes/nodeFuncs.h" |
25 | 22 | #include"parser/parse_agg.h" |
|
29 | 26 | #include"parser/parse_target.h" |
30 | 27 | #include"parser/parse_type.h" |
31 | 28 | #include"utils/builtins.h" |
32 | | -#include"utils/fmgroids.h" |
33 | 29 | #include"utils/lsyscache.h" |
34 | 30 | #include"utils/syscache.h" |
35 | 31 |
|
@@ -511,9 +507,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, |
511 | 507 | retval= (Node*)wfunc; |
512 | 508 | } |
513 | 509 |
|
514 | | -/* Hack to protect pg_get_expr() against misuse */ |
515 | | -check_pg_get_expr_args(pstate,funcid,fargs); |
516 | | - |
517 | 510 | returnretval; |
518 | 511 | } |
519 | 512 |
|
@@ -1600,107 +1593,3 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError) |
1600 | 1593 |
|
1601 | 1594 | returnoid; |
1602 | 1595 | } |
1603 | | - |
1604 | | - |
1605 | | -/* |
1606 | | - * pg_get_expr() is a system function that exposes the expression |
1607 | | - * deparsing functionality in ruleutils.c to users. Very handy, but it was |
1608 | | - * later realized that the functions in ruleutils.c don't check the input |
1609 | | - * rigorously, assuming it to come from system catalogs and to therefore |
1610 | | - * be valid. That makes it easy for a user to crash the backend by passing |
1611 | | - * a maliciously crafted string representation of an expression to |
1612 | | - * pg_get_expr(). |
1613 | | - * |
1614 | | - * There's a lot of code in ruleutils.c, so it's not feasible to add |
1615 | | - * water-proof input checking after the fact. Even if we did it once, it |
1616 | | - * would need to be taken into account in any future patches too. |
1617 | | - * |
1618 | | - * Instead, we restrict pg_rule_expr() to only allow input from system |
1619 | | - * catalogs. This is a hack, but it's the most robust and easiest |
1620 | | - * to backpatch way of plugging the vulnerability. |
1621 | | - * |
1622 | | - * This is transparent to the typical usage pattern of |
1623 | | - * "pg_get_expr(systemcolumn, ...)", but will break "pg_get_expr('foo', |
1624 | | - * ...)", even if 'foo' is a valid expression fetched earlier from a |
1625 | | - * system catalog. Hopefully there aren't many clients doing that out there. |
1626 | | - */ |
1627 | | -void |
1628 | | -check_pg_get_expr_args(ParseState*pstate,Oidfnoid,List*args) |
1629 | | -{ |
1630 | | -boolallowed= false; |
1631 | | -Node*arg; |
1632 | | -intnetlevelsup; |
1633 | | - |
1634 | | -/* if not being called for pg_get_expr, do nothing */ |
1635 | | -if (fnoid!=F_PG_GET_EXPR&&fnoid!=F_PG_GET_EXPR_EXT) |
1636 | | -return; |
1637 | | - |
1638 | | -/* superusers are allowed to call it anyway (dubious) */ |
1639 | | -if (superuser()) |
1640 | | -return; |
1641 | | - |
1642 | | -/* |
1643 | | - * The first argument must be a Var referencing one of the allowed |
1644 | | - * system-catalog columns. It could be a join alias Var, though. |
1645 | | - */ |
1646 | | -Assert(list_length(args)>1); |
1647 | | -arg= (Node*)linitial(args); |
1648 | | -netlevelsup=0; |
1649 | | - |
1650 | | -restart: |
1651 | | -if (IsA(arg,Var)) |
1652 | | -{ |
1653 | | -Var*var= (Var*)arg; |
1654 | | -RangeTblEntry*rte; |
1655 | | - |
1656 | | -netlevelsup+=var->varlevelsup; |
1657 | | -rte=GetRTEByRangeTablePosn(pstate,var->varno,netlevelsup); |
1658 | | - |
1659 | | -if (rte->rtekind==RTE_JOIN) |
1660 | | -{ |
1661 | | -/* Expand join alias reference */ |
1662 | | -if (var->varattno>0&& |
1663 | | -var->varattno <=list_length(rte->joinaliasvars)) |
1664 | | -{ |
1665 | | -arg= (Node*)list_nth(rte->joinaliasvars,var->varattno-1); |
1666 | | -gotorestart; |
1667 | | -} |
1668 | | -} |
1669 | | -elseif (rte->rtekind==RTE_RELATION) |
1670 | | -{ |
1671 | | -switch (rte->relid) |
1672 | | -{ |
1673 | | -caseIndexRelationId: |
1674 | | -if (var->varattno==Anum_pg_index_indexprs|| |
1675 | | -var->varattno==Anum_pg_index_indpred) |
1676 | | -allowed= true; |
1677 | | -break; |
1678 | | - |
1679 | | -caseAttrDefaultRelationId: |
1680 | | -if (var->varattno==Anum_pg_attrdef_adbin) |
1681 | | -allowed= true; |
1682 | | -break; |
1683 | | - |
1684 | | -caseProcedureRelationId: |
1685 | | -if (var->varattno==Anum_pg_proc_proargdefaults) |
1686 | | -allowed= true; |
1687 | | -break; |
1688 | | - |
1689 | | -caseConstraintRelationId: |
1690 | | -if (var->varattno==Anum_pg_constraint_conbin) |
1691 | | -allowed= true; |
1692 | | -break; |
1693 | | - |
1694 | | -caseTypeRelationId: |
1695 | | -if (var->varattno==Anum_pg_type_typdefaultbin) |
1696 | | -allowed= true; |
1697 | | -break; |
1698 | | -} |
1699 | | -} |
1700 | | -} |
1701 | | - |
1702 | | -if (!allowed) |
1703 | | -ereport(ERROR, |
1704 | | -(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
1705 | | -errmsg("argument to pg_get_expr() must come from system catalogs"))); |
1706 | | -} |