diff options
author | Jeff Davis | 2023-06-09 18:20:47 +0000 |
---|---|---|
committer | Jeff Davis | 2023-06-09 18:20:47 +0000 |
commit | 05e17373517114167d002494e004fa0aa32d1fd1 (patch) | |
tree | 2d96a124ad8a75d5d717d930f634c985f48e4166 /src/backend | |
parent | 9aee26a491ba9b7ceff40e6192183ab7200b6bfb (diff) |
Fix search_path to a safe value during maintenance operations.
While executing maintenance operations (ANALYZE, CLUSTER, REFRESH
MATERIALIZED VIEW, REINDEX, or VACUUM), set search_path to
'pg_catalog, pg_temp' to prevent inconsistent behavior.
Functions that are used for functional indexes, in index expressions,
or in materialized views and depend on a different search path must be
declared with CREATE FUNCTION ... SET search_path='...'.
This change addresses a security risk introduced in commit 60684dd834,
where a role with MAINTAIN privileges on a table may be able to
escalate privileges to the table owner. That commit is not yet part of
any release, so no need to backpatch.
Discussion: https://postgr.es/m/e44327179e5c9015c8dda67351c04da552066017.camel%40j-davis.com
Reviewed-by: Greg Stark
Reviewed-by: Nathan Bossart
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/brin/brin.c | 2 | ||||
-rw-r--r-- | src/backend/catalog/index.c | 8 | ||||
-rw-r--r-- | src/backend/commands/analyze.c | 2 | ||||
-rw-r--r-- | src/backend/commands/cluster.c | 2 | ||||
-rw-r--r-- | src/backend/commands/indexcmds.c | 6 | ||||
-rw-r--r-- | src/backend/commands/matview.c | 2 | ||||
-rw-r--r-- | src/backend/commands/vacuum.c | 2 |
7 files changed, 24 insertions, 0 deletions
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 3c6a956eaa3..11e78cb62c7 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -1066,6 +1066,8 @@ brin_summarize_range(PG_FUNCTION_ARGS) SetUserIdAndSecContext(heapRel->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); } else { diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 352e43d0e61..e8337041ac9 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -1475,6 +1475,8 @@ index_concurrently_build(Oid heapRelationId, SetUserIdAndSecContext(heapRel->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); indexRelation = index_open(indexRelationId, RowExclusiveLock); @@ -3006,6 +3008,8 @@ index_build(Relation heapRelation, SetUserIdAndSecContext(heapRelation->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); /* Set up initial progress report status */ { @@ -3341,6 +3345,8 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) SetUserIdAndSecContext(heapRelation->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); indexRelation = index_open(indexId, RowExclusiveLock); @@ -3601,6 +3607,8 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, SetUserIdAndSecContext(heapRelation->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); if (progress) { diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 52ef462dba3..2fdd1804976 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -348,6 +348,8 @@ do_analyze_rel(Relation onerel, VacuumParams *params, SetUserIdAndSecContext(onerel->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); /* measure elapsed time iff autovacuum logging requires it */ if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0) diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 369fea7c046..c94a3e20d61 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -355,6 +355,8 @@ cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params) SetUserIdAndSecContext(OldHeap->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); /* * Since we may open a new transaction for each relation, we have to check diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index a5168c9f097..a7c6a3dc7ad 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -575,6 +575,8 @@ DefineIndex(Oid relationId, int root_save_nestlevel; root_save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); /* * Some callers need us to run with an empty default_tablespace; this is a @@ -1300,6 +1302,8 @@ DefineIndex(Oid relationId, SetUserIdAndSecContext(childrel->rd_rel->relowner, child_save_sec_context | SECURITY_RESTRICTED_OPERATION); child_save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); /* * Don't try to create indexes on foreign tables, though. Skip @@ -3753,6 +3757,8 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params) SetUserIdAndSecContext(heapRel->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); /* determine safety of this index for set_indexsafe_procflags */ idx->safe = (indexRel->rd_indexprs == NIL && diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index f9a3bdfc3ab..9114a7924c8 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -179,6 +179,8 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, SetUserIdAndSecContext(relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); /* Make sure it is a materialized view. */ if (matviewRel->rd_rel->relkind != RELKIND_MATVIEW) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a843f9ad926..c0826117973 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2172,6 +2172,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, SetUserIdAndSecContext(rel->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET, + PGC_S_SESSION); /* * If PROCESS_MAIN is set (the default), it's time to vacuum the main |