bug_fix_childrel_stat_access_v1.patch

application/octet-stream

Filename: bug_fix_childrel_stat_access_v1.patch
Type: application/octet-stream
Part: 0
Message: Re: CVE-2017-7484-induced bugs, or, btree cmp functions are not leakproof?

Patch

Format: unified
Series: patch v1
File+
src/backend/optimizer/util/relnode.c 23 0
src/backend/utils/adt/selfuncs.c 28 1
src/include/nodes/relation.h 1 0
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 39f5729..d3bfe80 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -204,6 +204,29 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
 	rel->partitioned_child_rels = NIL;
 
 	/*
+	 * Pass top parent's relid down the inheritance hierarchy. If the parent
+	 * has inh_root_parent set then pass it down.
+	 */
+	if (parent)
+	{
+		if (parent->inh_root_parent)
+			rel->inh_root_parent = parent->inh_root_parent;
+		else
+		{
+			RangeTblEntry *parent_rte;
+
+			parent_rte = root->simple_rte_array[parent->relid];
+
+			if (parent_rte->rtekind == RTE_RELATION)
+				rel->inh_root_parent = parent->relid;
+			else
+				rel->inh_root_parent = 0;
+		}
+	}
+	else
+		rel->inh_root_parent = 0;
+
+	/*
 	 * Pass top parent's relids down the inheritance hierarchy. If the parent
 	 * has top_parent_relids set, it's a direct or an indirect child of the
 	 * top parent indicated by top_parent_relids. By extension this child is
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index e0ece74..3b982ba 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -4924,8 +4924,24 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
 							{
 								/* Get index's table for permission check */
 								RangeTblEntry *rte;
+								RelOptInfo	*rel = index->rel;
+
+								/*
+								 * For the child partition fetch the index of
+								 * the root parent.
+								 */
+								if (rel->inh_root_parent)
+								{
+									rte = planner_rt_fetch(rel->inh_root_parent,
+														   root);
+									/*
+									 * FIXME: convert child varattno to the
+									 * parent varattno.
+									 */
+								}
+								else
+									rte = planner_rt_fetch(rel->relid, root);
 
-								rte = planner_rt_fetch(index->rel->relid, root);
 								Assert(rte->rtekind == RTE_RELATION);
 
 								/*
@@ -4998,6 +5014,17 @@ examine_simple_variable(PlannerInfo *root, Var *var,
 
 		if (HeapTupleIsValid(vardata->statsTuple))
 		{
+			RelOptInfo *rel;
+
+			rel = root->simple_rel_array[var->varno];
+
+			/* For the child partition fetch the index of the root parent. */
+			if (rel->inh_root_parent)
+			{
+				rte = root->simple_rte_array[rel->inh_root_parent];
+
+				/* FIXME: convert child varattno to the parent varattno. */
+			}
 			/* check if user has permission to read this column */
 			vardata->acl_ok =
 				(pg_class_aclcheck(rte->relid, GetUserId(),
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 88d3723..9688fec 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -694,6 +694,7 @@ typedef struct RelOptInfo
 									 * rel) */
 
 	/* used for partitioned relations */
+	Index		inh_root_parent;	/* RTI index of the inheritance root. */
 	PartitionScheme part_scheme;	/* Partitioning scheme. */
 	int			nparts;			/* number of partitions */
 	struct PartitionBoundInfoData *boundinfo;	/* Partition bounds */