aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-09-03 22:09:06 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-09-03 22:09:06 +0000
commitfd28d83bdc1d357d2e21e416cf52c0e20ab6da16 (patch)
treea4bc7ca8463086b1c4237fdcff4212ab2d82d198 /src/backend
parent8422728a2bf00f997058411897dc1016daafdbe3 (diff)
downloadpostgresql-fd28d83bdc1d357d2e21e416cf52c0e20ab6da16.tar.gz
postgresql-fd28d83bdc1d357d2e21e416cf52c0e20ab6da16.zip
Disallow RESET ROLE and RESET SESSION AUTHORIZATION inside security-definer
functions. This extends the previous patch that forbade SETting these variables inside security-definer functions. RESET is equally a security hole, since it would allow regaining privileges of the caller; furthermore it can trigger Assert failures and perhaps other internal errors, since the code is not expecting these variables to change in such contexts. The previous patch did not cover this case because assign hooks don't really have enough information, so move the responsibility for preventing this into guc.c. Problem discovered by Heikki Linnakangas. Security: no CVE assigned yet, extends CVE-2007-6600
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/variable.c18
-rw-r--r--src/backend/utils/misc/guc.c30
2 files changed, 29 insertions, 19 deletions
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 6a856170d6c..4076312799d 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.88.2.4 2008/01/03 21:25:33 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.88.2.5 2009/09/03 22:09:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -773,22 +773,6 @@ assign_session_authorization(const char *value, bool doit, bool interactive)
/* not a saved ID, so look it up */
HeapTuple userTup;
- 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.
- */
- if (interactive)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot set session authorization within security-definer function")));
- return NULL;
- }
-
if (!IsTransactionState())
{
/*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 227ecf62fda..5e72d578913 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.164.2.5 2006/05/21 20:11:58 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.164.2.6 2009/09/03 22:09:05 tgl Exp $
*
*--------------------------------------------------------------------
*/
@@ -1511,7 +1511,7 @@ static struct config_string ConfigureNamesString[] =
{"session_authorization", PGC_USERSET, UNGROUPED,
gettext_noop("Shows the session user name."),
NULL,
- GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+ GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_DEF
},
&session_authorization_string,
NULL, assign_session_authorization, show_session_authorization
@@ -2514,6 +2514,32 @@ set_config_option(const char *name, const char *value,
break;
}
+ /*
+ * Disallow changing GUC_NOT_WHILE_SEC_DEF values if we are inside a
+ * security-definer function. We can reject this regardless of
+ * the context or source, mainly because sources that it might be
+ * reasonable to override for won't be seen while inside a function.
+ *
+ * Note: variables marked GUC_NOT_WHILE_SEC_DEF should probably be marked
+ * GUC_NO_RESET_ALL as well, because ResetAllOptions() doesn't check this.
+ *
+ * Note: this flag is currently used for "session_authorization".
+ * We need to prohibit this because when we exit the sec-def
+ * context, GUC won't be notified, leaving things out of sync.
+ *
+ * XXX it would be nice to allow these cases in future, with the behavior
+ * being that the SET's effects end when the security definer context is
+ * exited.
+ */
+ if ((record->flags & GUC_NOT_WHILE_SEC_DEF) && InSecurityDefinerContext())
+ {
+ ereport(elevel,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("cannot set parameter \"%s\" within security-definer function",
+ name)));
+ return false;
+ }
+
/* Should we report errors interactively? */
interactive = (source >= PGC_S_SESSION);