提交 54a2bda7 编写于 作者: J Joao Pereira 提交者: =

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 f223bb7aCo-authored-by: NTaylor Vesely <tvesely@pivotal.io>
(cherry picked from commit 39560a95615771768b7381842fffe4af9b4284b6)
上级 387cb703
......@@ -50,7 +50,6 @@ static Node *ParseComplexProjection(ParseState *pstate, char *funcname,
Node *first_arg, int location);
static void unknown_attribute(ParseState *pstate, Node *relref, char *attname,
int location);
static bool check_pg_get_expr_arg(ParseState *pstate, Node *arg, int netlevelsup);
typedef struct
{
......@@ -633,9 +632,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
}
}
/* Hack to protect pg_get_expr() against misuse */
check_pg_get_expr_args(pstate, funcid, fargs);
return retval;
}
......@@ -1856,56 +1852,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)
{
......
......@@ -1076,9 +1076,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;
}
......@@ -1151,9 +1148,6 @@ make_op_expr(ParseState *pstate, Operator op,
result->opretset = get_func_retset(opform->oprcode);
result->args = args;
/* Hack to protect pg_get_expr() against misuse */
check_pg_get_expr_args(pstate, result->opfuncid, args);
return (Expr *) result;
}
......
......@@ -83,8 +83,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.
先完成此消息的编辑!
想要评论请 注册