1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-12 15:23:02 +03:00

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
This commit is contained in:
Tom Lane
2008-01-03 21:25:00 +00:00
parent 69abe8294b
commit 108b19d860
11 changed files with 184 additions and 93 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.80 2004/12/31 21:59:41 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.80.4.1 2008/01/03 21:25:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -110,6 +110,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
numrows;
double totalrows;
HeapTuple *rows;
AclId save_userid;
bool save_secdefcxt;
if (vacstmt->verbose)
elevel = INFO;
@@ -199,6 +201,13 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
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);
/*
* Determine which columns to analyze
*
@@ -309,11 +318,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
* Quit if no analyzable columns
*/
if (attr_cnt <= 0 && !analyzableindex)
{
vac_close_indexes(nindexes, Irel, AccessShareLock);
relation_close(onerel, AccessShareLock);
return;
}
goto cleanup;
/*
* Determine how many rows we need to sample, using the worst case
@@ -426,6 +431,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
}
}
/* We skip to here if there were no analyzable columns */
cleanup:
/* Done with indexes */
vac_close_indexes(nindexes, Irel, NoLock);
@@ -435,6 +443,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
* entries we made in pg_statistic.)
*/
relation_close(onerel, NoLock);
/* Restore userid */
SetUserIdAndContext(save_userid, save_secdefcxt);
}
/*