aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/analyze.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-01-03 21:23:15 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-01-03 21:23:15 +0000
commiteedb068c0a7474fb11d67d03b0a9e1ded5df82c4 (patch)
tree1e5a19e0970f87fea7d5e2d243d5614318229f79 /src/backend/commands/analyze.c
parent98f27aaef34291246c09ce5d0e0fba4f4477467a (diff)
downloadpostgresql-eedb068c0a7474fb11d67d03b0a9e1ded5df82c4.tar.gz
postgresql-eedb068c0a7474fb11d67d03b0a9e1ded5df82c4.zip
Make standard maintenance operations (including VACUUM, ANALYZE, REINDEX,
and CLUSTER) execute as the table owner rather than the calling user, using the same privilege-switching mechanism already used for SECURITY DEFINER functions. The purpose of this change is to ensure that user-defined functions used in index definitions cannot acquire the privileges of a superuser account that is performing routine maintenance. While a function used in an index is supposed to be IMMUTABLE and thus not able to do anything very interesting, there are several easy ways around that restriction; and even if we could plug them all, there would remain a risk of reading sensitive information and broadcasting it through a covert channel such as CPU usage. To prevent bypassing this security measure, execution of SET SESSION AUTHORIZATION and SET ROLE is now forbidden within a SECURITY DEFINER context. Thanks to Itagaki Takahiro for reporting this vulnerability. Security: CVE-2007-6600
Diffstat (limited to 'src/backend/commands/analyze.c')
-rw-r--r--src/backend/commands/analyze.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index f39a9575bbf..82bb020bc57 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.113 2008/01/01 19:45:48 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.114 2008/01/03 21:23:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -119,6 +119,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
HeapTuple *rows;
PGRUsage ru0;
TimestampTz starttime = 0;
+ Oid save_userid;
+ bool save_secdefcxt;
if (vacstmt->verbose)
elevel = INFO;
@@ -202,6 +204,18 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
return;
}
+ ereport(elevel,
+ (errmsg("analyzing \"%s.%s\"",
+ get_namespace_name(RelationGetNamespace(onerel)),
+ RelationGetRelationName(onerel))));
+
+ /*
+ * Switch to the table owner's userid, so that any index functions are
+ * run as that user.
+ */
+ GetUserIdAndContext(&save_userid, &save_secdefcxt);
+ SetUserIdAndContext(onerel->rd_rel->relowner, true);
+
/* let others know what I'm doing */
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
MyProc->vacuumFlags |= PROC_IN_ANALYZE;
@@ -215,11 +229,6 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
starttime = GetCurrentTimestamp();
}
- ereport(elevel,
- (errmsg("analyzing \"%s.%s\"",
- get_namespace_name(RelationGetNamespace(onerel)),
- RelationGetRelationName(onerel))));
-
/*
* Determine which columns to analyze
*
@@ -344,9 +353,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
onerel->rd_rel->relisshared,
0, 0);
- vac_close_indexes(nindexes, Irel, AccessShareLock);
- relation_close(onerel, ShareUpdateExclusiveLock);
- return;
+ goto cleanup;
}
/*
@@ -466,6 +473,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
totalrows, totaldeadrows);
}
+ /* We skip to here if there were no analyzable columns */
+cleanup:
+
/* Done with indexes */
vac_close_indexes(nindexes, Irel, NoLock);
@@ -498,6 +508,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
MyProc->vacuumFlags &= ~PROC_IN_ANALYZE;
LWLockRelease(ProcArrayLock);
+
+ /* Restore userid */
+ SetUserIdAndContext(save_userid, save_secdefcxt);
}
/*