提交 9b2d6688 编写于 作者: J Joao Pereira 提交者: Pivotal@Madeira

Missmerge of commit from upstream

The commit 8ab6a6b4 from upstream removed the function
check_pg_get_expr_args and all the calls to it.
Nevertheless the merge brought it back and with it the
issue corrected on commit f223bb7aSigned-off-by: NTaylor Vesely <tvesely@pivotal.io>
Co-authored-by: NTaylor Vesely <tvesely@pivotal.io>
上级 f3e5c093
......@@ -45,7 +45,6 @@ static void unify_hypothetical_args(ParseState *pstate,
static Oid FuncNameAsType(List *funcname);
static Node *ParseComplexProjection(ParseState *pstate, char *funcname,
Node *first_arg, int location);
static bool check_pg_get_expr_arg(ParseState *pstate, Node *arg, int netlevelsup);
typedef struct
{
......@@ -797,9 +796,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
if (func_exec_location(funcid) != PROEXECLOCATION_ANY)
pstate->p_hasFuncsWithExecRestrictions = true;
/* Hack to protect pg_get_expr() against misuse */
check_pg_get_expr_args(pstate, funcid, fargs);
return retval;
}
......@@ -2155,56 +2151,6 @@ checkTableFunctions_walker(Node *node, check_table_func_context *context)
}
}
/*
* pg_get_expr() is a system function that exposes the expression
* deparsing functionality in ruleutils.c to users. Very handy, but it was
* later realized that the functions in ruleutils.c don't check the input
* rigorously, assuming it to come from system catalogs and to therefore
* be valid. That makes it easy for a user to crash the backend by passing
* a maliciously crafted string representation of an expression to
* pg_get_expr().
*
* There's a lot of code in ruleutils.c, so it's not feasible to add
* water-proof input checking after the fact. Even if we did it once, it
* would need to be taken into account in any future patches too.
*
* Instead, we restrict pg_rule_expr() to only allow input from system
* catalogs. This is a hack, but it's the most robust and easiest
* to backpatch way of plugging the vulnerability.
*
* This is transparent to the typical usage pattern of
* "pg_get_expr(systemcolumn, ...)", but will break "pg_get_expr('foo',
* ...)", even if 'foo' is a valid expression fetched earlier from a
* system catalog. Hopefully there aren't many clients doing that out there.
*/
void
check_pg_get_expr_args(ParseState *pstate, Oid fnoid, List *args)
{
Node *arg;
/* if not being called for pg_get_expr, do nothing */
if (fnoid != F_PG_GET_EXPR && fnoid != F_PG_GET_EXPR_EXT)
return;
/* superusers are allowed to call it anyway (dubious) */
if (superuser())
return;
/*
* The first argument must be a Var referencing one of the allowed
* system-catalog columns. It could be a join alias Var or subquery
* reference Var, though, so we need a recursive subroutine to chase
* through those possibilities.
*/
Assert(list_length(args) > 1);
arg = (Node *) linitial(args);
if (!check_pg_get_expr_arg(pstate, arg, 0))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("argument to pg_get_expr() must come from system catalogs")));
}
static bool
check_pg_get_expr_arg(ParseState *pstate, Node *arg, int netlevelsup)
{
......
......@@ -966,9 +966,6 @@ make_scalar_array_op(ParseState *pstate, List *opname,
ReleaseSysCache(tup);
/* Hack to protect pg_get_expr() against misuse */
check_pg_get_expr_args(pstate, result->opfuncid, args);
return (Expr *) result;
}
......
......@@ -79,8 +79,6 @@ extern Oid LookupFuncNameTypeNames(List *funcname, List *argtypes,
extern Oid LookupAggNameTypeNames(List *aggname, List *argtypes,
bool noError);
extern void check_pg_get_expr_args(ParseState *pstate, Oid fnoid, List *args);
extern void parseCheckTableFunctions(ParseState *pstate, Query *qry);
#endif /* PARSE_FUNC_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册