From c2f638a9491e103311161208715dfcbcb55a2fbd Mon Sep 17 00:00:00 2001
From: Pierre Ducroquet
Date: Sat, 6 Apr 2019 13:22:29 +0200
Subject: [PATCH] Use a different permission check path for indexes and
relations in pg_stats
pg_statistic contains information about both table attributes and functional indexes,
but the permission check done in pg_stats was only valid for table attributes.
This patch thus implements a seperate permission check for functional indexes, that
verifies the access for each attribute contained in the index.
---
src/backend/catalog/system_views.sql | 10 +++++++++-
src/test/regress/expected/rules.out | 4 +++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 72f786d6f8..a1e8ea969c 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -248,7 +248,15 @@ CREATE VIEW pg_stats WITH (security_barrier) AS
JOIN pg_attribute a ON (c.oid = attrelid AND attnum = s.staattnum)
LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
WHERE NOT attisdropped
- AND has_column_privilege(c.oid, a.attnum, 'select')
+ AND (c.relkind = 'r' AND has_column_privilege(c.oid, a.attnum, 'select'::text)
+ OR
+ (c.relkind = 'i' AND NOT(EXISTS(
+ SELECT 1 FROM pg_depend
+ WHERE pg_depend.objid = c.oid
+ AND pg_depend.refobjsubid > 0
+ AND NOT has_column_privilege(pg_depend.refobjid, pg_depend.refobjsubid::smallint, 'select'::text)))
+ )
+ )
AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
REVOKE ALL on pg_statistic FROM public;
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index bf7fca54ee..34953ae4f4 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2262,7 +2262,9 @@ pg_stats| SELECT n.nspname AS schemaname,
JOIN pg_class c ON ((c.oid = s.starelid)))
JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum))))
LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
- WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
+ WHERE ((NOT a.attisdropped) AND (((c.relkind = 'r'::"char") AND has_column_privilege(c.oid, a.attnum, 'select'::text)) OR ((c.relkind = 'i'::"char") AND (NOT (EXISTS ( SELECT 1
+ FROM pg_depend
+ WHERE ((pg_depend.objid = c.oid) AND (pg_depend.refobjsubid > 0) AND (NOT has_column_privilege(pg_depend.refobjid, (pg_depend.refobjsubid)::smallint, 'select'::text)))))))) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
pg_tables| SELECT n.nspname AS schemaname,
c.relname AS tablename,
pg_get_userbyid(c.relowner) AS tableowner,
--
2.20.1