1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-09 22:41:56 +03:00

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
This commit is contained in:
Jeff Davis
2023-06-09 11:20:47 -07:00
parent 9aee26a491
commit 05e1737351
15 changed files with 48 additions and 16 deletions

View File

@ -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)

View File

@ -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

View File

@ -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 &&

View File

@ -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)

View File

@ -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