76 lines
3.0 KiB
Diff
76 lines
3.0 KiB
Diff
From 1aebfbea83c4a3e1a0aba4b0910135dc5a45666c Mon Sep 17 00:00:00 2001
|
|
From: Dean Rasheed <dean.a.rasheed@gmail.com>
|
|
Date: Mon, 6 May 2019 11:38:43 +0100
|
|
Subject: [PATCH] Fix security checks for selectivity estimation functions with
|
|
RLS.
|
|
|
|
In commit e2d4ef8de8, security checks were added to prevent
|
|
user-supplied operators from running over data from pg_statistic
|
|
unless the user has table or column privileges on the table, or the
|
|
operator is leakproof. For a table with RLS, however, checking for
|
|
table or column privileges is insufficient, since that does not
|
|
guarantee that the user has permission to view all of the column's
|
|
data.
|
|
|
|
Fix this by also checking for securityQuals on the RTE, and insisting
|
|
that the operator be leakproof if there are any. Thus the
|
|
leakproofness check will only be skipped if there are no securityQuals
|
|
and the user has table or column privileges on the table -- i.e., only
|
|
if we know that the user has access to all the data in the column.
|
|
|
|
Back-patch to 9.5 where RLS was added.
|
|
|
|
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
|
|
|
|
Security: CVE-2019-10130
|
|
---
|
|
src/backend/utils/adt/selfuncs.c | 21 +++++++++++++++------
|
|
src/test/regress/expected/rowsecurity.out | 21 +++++++++++++++++++++
|
|
src/test/regress/sql/rowsecurity.sql | 20 ++++++++++++++++++++
|
|
3 files changed, 56 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
|
|
index b41991315520..514612857ad6 100644
|
|
--- a/src/backend/utils/adt/selfuncs.c
|
|
+++ b/src/backend/utils/adt/selfuncs.c
|
|
@@ -4597,9 +4597,13 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
|
|
* For simplicity, we insist on the whole
|
|
* table being selectable, rather than trying
|
|
* to identify which column(s) the index
|
|
- * depends on.
|
|
+ * depends on. Also require all rows to be
|
|
+ * selectable --- there must be no
|
|
+ * securityQuals from security barrier views
|
|
+ * or RLS policies.
|
|
*/
|
|
vardata->acl_ok =
|
|
+ rte->securityQuals == NIL &&
|
|
(pg_class_aclcheck(rte->relid, GetUserId(),
|
|
ACL_SELECT) == ACLCHECK_OK);
|
|
}
|
|
@@ -4663,12 +4667,17 @@ examine_simple_variable(PlannerInfo *root, Var *var,
|
|
|
|
if (HeapTupleIsValid(vardata->statsTuple))
|
|
{
|
|
- /* check if user has permission to read this column */
|
|
+ /*
|
|
+ * Check if user has permission to read this column. We require
|
|
+ * all rows to be accessible, so there must be no securityQuals
|
|
+ * from security barrier views or RLS policies.
|
|
+ */
|
|
vardata->acl_ok =
|
|
- (pg_class_aclcheck(rte->relid, GetUserId(),
|
|
- ACL_SELECT) == ACLCHECK_OK) ||
|
|
- (pg_attribute_aclcheck(rte->relid, var->varattno, GetUserId(),
|
|
- ACL_SELECT) == ACLCHECK_OK);
|
|
+ rte->securityQuals == NIL &&
|
|
+ ((pg_class_aclcheck(rte->relid, GetUserId(),
|
|
+ ACL_SELECT) == ACLCHECK_OK) ||
|
|
+ (pg_attribute_aclcheck(rte->relid, var->varattno, GetUserId(),
|
|
+ ACL_SELECT) == ACLCHECK_OK));
|
|
}
|
|
else
|
|
{
|
|
--
|
|
2.11.0
|