On 15/06/10 10:31, Heikki Linnakangas wrote:
You could avoid changing the meaning of fn_expr by putting the check in
the parse analysis phase, into transformFuncCall(). That would feel
safer at least for back-branches.

Here's a patch using that approach.

I grepped through PostgreSQL and pgadmin source code to find the system columns where valid node-strings are stored:

pg_index.indexprs
pg_index.indprep
pg_attrdef.adbin
pg_proc.proargdefaults
pg_constraint.conbin

Am I missing anything?

--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 5e60374..7c375a9 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -16,6 +16,9 @@
 #include "postgres.h"
 
 #include "catalog/pg_type.h"
+#include "catalog/pg_attrdef.h"
+#include "catalog/pg_constraint.h"
+#include "catalog/pg_proc.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
@@ -30,6 +33,7 @@
 #include "parser/parse_target.h"
 #include "parser/parse_type.h"
 #include "utils/builtins.h"
+#include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/xml.h"
 
@@ -1210,6 +1214,7 @@ transformFuncCall(ParseState *pstate, FuncCall *fn)
 {
 	List	   *targs;
 	ListCell   *args;
+	Node	   *result;
 
 	/* Transform the list of arguments ... */
 	targs = NIL;
@@ -1220,7 +1225,7 @@ transformFuncCall(ParseState *pstate, FuncCall *fn)
 	}
 
 	/* ... and hand off to ParseFuncOrColumn */
-	return ParseFuncOrColumn(pstate,
+	result = ParseFuncOrColumn(pstate,
 							 fn->funcname,
 							 targs,
 							 fn->agg_order,
@@ -1230,6 +1235,58 @@ transformFuncCall(ParseState *pstate, FuncCall *fn)
 							 fn->over,
 							 false,
 							 fn->location);
+
+	/* FIXME explain why this hack is needed */
+	if (result && IsA(result, FuncExpr) && !superuser())
+	{
+		FuncExpr *fe = (FuncExpr *) result;
+		if (fe->funcid == F_PG_GET_EXPR || fe->funcid == F_PG_GET_EXPR_EXT)
+		{
+			Expr *arg = linitial(fe->args);
+			bool allowed = false;
+
+			/*
+			 * Check that the argument came directly from one of the
+			 * allowed system catalog columns
+			 */
+			if (IsA(arg, Var))
+			{
+				Var *var = (Var *) arg;
+				RangeTblEntry *rte;
+
+				rte = GetRTEByRangeTablePosn(pstate,
+											 var->varno, var->varlevelsup);
+
+				switch(rte->relid)
+				{
+					case IndexRelationId:
+						if (var->varattno == Anum_pg_index_indexprs ||
+							var->varattno == Anum_pg_index_indpred)
+							allowed = true;
+						break;
+
+					case AttrDefaultRelationId:
+						if (var->varattno == Anum_pg_attrdef_adbin)
+							allowed = true;
+						break;
+
+					case ProcedureRelationId:
+						if (var->varattno == Anum_pg_proc_proargdefaults)
+							allowed = true;
+						break;
+					case ConstraintRelationId:
+						if (var->varattno == Anum_pg_constraint_conbin)
+							allowed = true;
+						break;
+				}
+			}
+			if (!allowed)
+				ereport(ERROR,
+						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+						 errmsg("argument to pg_get_expr() must come from system catalogs")));
+		}
+	}
+	return result;
 }
 
 static Node *
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index 575fa86..32c4fa9 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -29,6 +29,7 @@
 #include "tcop/fastpath.h"
 #include "tcop/tcopprot.h"
 #include "utils/acl.h"
+#include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
@@ -347,6 +348,11 @@ HandleFunctionRequest(StringInfo msgBuf)
 		aclcheck_error(aclresult, ACL_KIND_PROC,
 					   get_func_name(fid));
 
+	if ((fid == F_PG_GET_EXPR || fid == F_PG_GET_EXPR_EXT) && !superuser())
+		ereport(ERROR,
+				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+				 errmsg("argument to pg_get_expr() must come from system catalogs")));
+
 	/*
 	 * Prepare function call info block and insert arguments.
 	 */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to