mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +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:
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.124 2008/01/01 19:45:49 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.125 2008/01/03 21:23:15 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -717,6 +717,21 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
|
||||
/* not a saved ID, so look it up */
|
||||
HeapTuple roleTup;
|
||||
|
||||
if (InSecurityDefinerContext())
|
||||
{
|
||||
/*
|
||||
* Disallow SET SESSION AUTHORIZATION inside a security definer
|
||||
* context. We need to do this because when we exit the context,
|
||||
* GUC won't be notified, leaving things out of sync. Note that
|
||||
* this test is positioned so that restoring a previously saved
|
||||
* setting isn't prevented.
|
||||
*/
|
||||
ereport(GUC_complaint_elevel(source),
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot set session authorization within security-definer function")));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!IsTransactionState())
|
||||
{
|
||||
/*
|
||||
@ -823,6 +838,24 @@ assign_role(const char *value, bool doit, GucSource source)
|
||||
}
|
||||
}
|
||||
|
||||
if (roleid == InvalidOid && InSecurityDefinerContext())
|
||||
{
|
||||
/*
|
||||
* Disallow SET ROLE inside a security definer context. We need to do
|
||||
* this because when we exit the context, GUC won't be notified,
|
||||
* leaving things out of sync. Note that this test is arranged so
|
||||
* that restoring a previously saved setting isn't prevented.
|
||||
*
|
||||
* XXX it would be nice to allow this case in future, with the
|
||||
* behavior being that the SET ROLE's effects end when the security
|
||||
* definer context is exited.
|
||||
*/
|
||||
ereport(GUC_complaint_elevel(source),
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot set role within security-definer function")));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (roleid == InvalidOid &&
|
||||
strcmp(actual_rolename, "none") != 0)
|
||||
{
|
||||
|
Reference in New Issue
Block a user