0002-Use-permissions-granted-on-parent-to-read-stats-on-o.patch

text/plain

Filename: 0002-Use-permissions-granted-on-parent-to-read-stats-on-o.patch
Type: text/plain
Part: 1
Message: Re: CVE-2017-7484-induced bugs, or, btree cmp functions are not leakproof?

Patch

Format: format-patch
Series: patch 0002
Subject: Use permissions granted on parent to read stats on otherrel children
File+
src/backend/utils/adt/selfuncs.c 55 3
From e7ce03017391f7472a9d30b039447d66f1d956c6 Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Fri, 2 Nov 2018 16:48:25 +0900
Subject: [PATCH 2/2] Use permissions granted on parent to read stats on
 otherrel children

Author: Dilip Kumar
Reviewed by: Amit Langote
---
 src/backend/utils/adt/selfuncs.c | 58 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 55 insertions(+), 3 deletions(-)

diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index e0ece74bb9..698a4eca63 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -4924,8 +4924,18 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
 							{
 								/* Get index's table for permission check */
 								RangeTblEntry *rte;
+								RelOptInfo	*rel = index->rel;
+
+								/*
+								 * For a child table, check permissions using
+								 * parent's RTE.
+								 */
+								if (rel->inh_root_parent)
+									rte = planner_rt_fetch(rel->inh_root_parent,
+														   root);
+								else
+									rte = planner_rt_fetch(rel->relid, root);
 
-								rte = planner_rt_fetch(index->rel->relid, root);
 								Assert(rte->rtekind == RTE_RELATION);
 
 								/*
@@ -4998,11 +5008,53 @@ examine_simple_variable(PlannerInfo *root, Var *var,
 
 		if (HeapTupleIsValid(vardata->statsTuple))
 		{
+			RelOptInfo *rel;
+			Oid	relid = rte->relid;
+			int	varattno = var->varattno;
+
+			rel = root->simple_rel_array[var->varno];
+
+			/*
+			 * For an inheritance child table, check permissions using the
+			 * root parent's RTE and columns.
+			 */
+			if (rel->inh_root_parent)
+			{
+				relid = planner_rt_fetch(rel->inh_root_parent, root)->relid;
+
+				/*
+				 * Must find out the column's attribute number per the root
+				 * parent's schema.
+				 */
+				if (varattno > 0)
+				{
+					AppendRelInfo *appinfo = root->append_rel_array[rel->relid];
+					ListCell   *l;
+					bool		found = false;
+
+					Assert(appinfo != NULL);
+					varattno = 1;
+					foreach(l, appinfo->translated_vars)
+					{
+						if (equal(var, lfirst(l)))
+						{
+							found = true;
+							break;
+						}
+						varattno++;
+					}
+					/*
+					 * The query can only select columns present in the parent
+					 * table, so we must've found one in translated_vars.
+					 */
+					Assert(found);
+				}
+			}
 			/* check if user has permission to read this column */
 			vardata->acl_ok =
-				(pg_class_aclcheck(rte->relid, GetUserId(),
+				(pg_class_aclcheck(relid, GetUserId(),
 								   ACL_SELECT) == ACLCHECK_OK) ||
-				(pg_attribute_aclcheck(rte->relid, var->varattno, GetUserId(),
+				(pg_attribute_aclcheck(relid, varattno, GetUserId(),
 									   ACL_SELECT) == ACLCHECK_OK);
 		}
 		else
-- 
2.11.0