From 54a2bda7d72c46a00aa7db8467e5cbbc68a6ae5e Mon Sep 17 00:00:00 2001 From: Joao Pereira Date: Fri, 27 Jul 2018 12:23:47 -0400 Subject: [PATCH] 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 f223bb7a4 Co-authored-by: Taylor Vesely (cherry picked from commit 39560a95615771768b7381842fffe4af9b4284b6) --- src/backend/parser/parse_func.c | 54 --------------------------------- src/backend/parser/parse_oper.c | 6 ---- src/include/parser/parse_func.h | 2 -- 3 files changed, 62 deletions(-) diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 93b6e2eecd..01fd76eeae 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -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) { diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c index deb810e1d2..de7c3fb69c 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -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; } diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h index 2ef14d7b7e..62b9ef99b1 100644 --- a/src/include/parser/parse_func.h +++ b/src/include/parser/parse_func.h @@ -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 */ -- GitLab