diff options
author | Noah Misch | 2015-09-21 00:47:17 +0000 |
---|---|---|
committer | Pavan Deolasee | 2016-10-26 07:55:36 +0000 |
commit | 46a5cfb74e863b26a131c58d3b389dd5f2bfb707 (patch) | |
tree | cc34d210200e1a71ddfd83333bc00eb01872b664 | |
parent | 10b83c1210e66eca38cc726443a93f40acdbcbd6 (diff) |
Remove the SECURITY_ROW_LEVEL_DISABLED security context bit.
This commit's parent made superfluous the bit's sole usage. Referential
integrity checks have long run as the subject table's owner, and that
now implies RLS bypass. Safe use of the bit was tricky, requiring
strict control over the SQL expressions evaluating therein. Back-patch
to 9.5, where the bit was introduced.
Based on a patch by Stephen Frost.
-rw-r--r-- | src/backend/utils/adt/ri_triggers.c | 17 | ||||
-rw-r--r-- | src/backend/utils/cache/plancache.c | 13 | ||||
-rw-r--r-- | src/backend/utils/misc/rls.c | 4 | ||||
-rw-r--r-- | src/include/miscadmin.h | 1 | ||||
-rw-r--r-- | src/include/utils/plancache.h | 5 |
5 files changed, 9 insertions, 31 deletions
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 2b6116b667..3f9d568760 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -2977,7 +2977,6 @@ ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes, Relation query_rel; Oid save_userid; int save_sec_context; - int temp_sec_context; /* * Use the query type code to determine whether the query is run against @@ -2990,22 +2989,8 @@ ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes, /* Switch to proper UID to perform check as */ GetUserIdAndSecContext(&save_userid, &save_sec_context); - - /* - * Row-level security should be disabled in the case where a foreign-key - * relation is queried to check existence of tuples that references the - * primary-key being modified. - */ - temp_sec_context = save_sec_context | SECURITY_LOCAL_USERID_CHANGE; - if (qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK - || qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK_FROM_PK - || qkey->constr_queryno == RI_PLAN_RESTRICT_DEL_CHECKREF - || qkey->constr_queryno == RI_PLAN_RESTRICT_UPD_CHECKREF) - temp_sec_context |= SECURITY_ROW_LEVEL_DISABLED; - - SetUserIdAndSecContext(RelationGetForm(query_rel)->relowner, - temp_sec_context); + save_sec_context | SECURITY_LOCAL_USERID_CHANGE); /* Create the plan */ qplan = SPI_prepare(querystr, nargs, argtypes); diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index 466af13bb9..49c047e072 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -225,8 +225,6 @@ CreateCachedPlan(Node *raw_parse_tree, plansource->total_custom_cost = 0; plansource->num_custom_plans = 0; plansource->hasRowSecurity = false; - plansource->rowSecurityDisabled - = (security_context & SECURITY_ROW_LEVEL_DISABLED) != 0; plansource->planUserId = InvalidOid; plansource->row_security_env = false; @@ -650,17 +648,10 @@ RevalidateCachedQuery(CachedPlanSource *plansource) } /* - * Check if row security is enabled for this query and things have changed - * such that we need to invalidate this plan and rebuild it. Note that if - * row security was explicitly disabled (eg: this is a FK check plan) then - * we don't invalidate due to RLS. - * - * Otherwise, if the plan has a possible RLS dependency, force a replan if - * either the role under which the plan was planned or the row_security - * setting has been changed. + * If the plan has a possible RLS dependency, force a replan if either the + * role or the row_security setting has changed. */ if (plansource->is_valid - && !plansource->rowSecurityDisabled && plansource->hasRowSecurity && (plansource->planUserId != GetUserId() || plansource->row_security_env != row_security)) diff --git a/src/backend/utils/misc/rls.c b/src/backend/utils/misc/rls.c index 44cb374303..3350f10c9f 100644 --- a/src/backend/utils/misc/rls.c +++ b/src/backend/utils/misc/rls.c @@ -53,6 +53,10 @@ check_enable_rls(Oid relid, Oid checkAsUser, bool noError) bool relrowsecurity; Oid user_id = checkAsUser ? checkAsUser : GetUserId(); + /* Nothing to do for built-in relations */ + if (relid < FirstNormalObjectId) + return RLS_NONE; + tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tuple)) return RLS_NONE; diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index b6ea2ae742..be1cb664df 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -291,7 +291,6 @@ extern int trace_recovery(int trace_level); /* flags to be OR'd to form sec_context */ #define SECURITY_LOCAL_USERID_CHANGE 0x0001 #define SECURITY_RESTRICTED_OPERATION 0x0002 -#define SECURITY_ROW_LEVEL_DISABLED 0x0004 extern char *DatabasePath; diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h index 19654fb48c..af73478c40 100644 --- a/src/include/utils/plancache.h +++ b/src/include/utils/plancache.h @@ -113,9 +113,8 @@ typedef struct CachedPlanSource #ifdef PGXC char *stmt_name; /* If set, this is a copy of prepared stmt name */ #endif - bool hasRowSecurity; /* planned with row security? */ - int row_security_env; /* row security setting when planned */ - bool rowSecurityDisabled; /* is row security disabled? */ + bool hasRowSecurity; /* planned with row security? */ + bool row_security_env; /* row security setting when planned */ } CachedPlanSource; /* |