diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-01-03 21:25:34 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-01-03 21:25:34 +0000 |
commit | 230d5cfc4739bc4963c8d67e4a7cd84abe53ef93 (patch) | |
tree | 0fa8d138ed251e873bd55a4e7b402fbdd9f57488 /src/backend/access/transam/xact.c | |
parent | 0776cb2116f4eaec743f1e304c1255c318a20d1f (diff) |
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/access/transam/xact.c')
-rw-r--r-- | src/backend/access/transam/xact.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index c8a68b5fb3a..36bfc3f5426 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.156.2.4 2007/04/26 23:25:40 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.156.2.5 2008/01/03 21:25:33 tgl Exp $ * * NOTES * Transaction aborts can now occur two ways: @@ -204,6 +204,8 @@ static TransactionStateData CurrentTransactionStateData = { static TransactionState CurrentTransactionState = &CurrentTransactionStateData; +static AclId prevUser; /* CurrentUserId at transaction start */ + /* * User-tweakable parameters */ @@ -849,6 +851,7 @@ static void StartTransaction(void) { TransactionState s = CurrentTransactionState; + bool prevSecDefCxt; /* * check the current transaction state @@ -882,6 +885,10 @@ StartTransaction(void) s->commandId = FirstCommandId; s->startTime = GetCurrentAbsoluteTimeUsec(&(s->startTimeUsec)); + GetUserIdAndContext(&prevUser, &prevSecDefCxt); + /* SecurityDefinerContext should never be set outside a transaction */ + Assert(!prevSecDefCxt); + /* * initialize the various transaction subsystems */ @@ -1074,9 +1081,16 @@ AbortTransaction(void) AtAbort_Memory(); /* - * Reset user id which might have been changed transiently + * Reset user ID which might have been changed transiently. We need this + * to clean up in case control escaped out of a SECURITY DEFINER function + * or other local change of CurrentUserId; therefore, the prior value + * of SecurityDefinerContext also needs to be restored. + * + * (Note: it is not necessary to restore session authorization + * setting here because that can only be changed via GUC, and GUC will + * take care of rolling it back if need be.) */ - SetUserId(GetSessionUserId()); + SetUserIdAndContext(prevUser, false); /* * do abort processing |