aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-02-23 15:39:07 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2012-02-23 15:39:07 -0500
commitde323d534c8989bc713c1ac5313024cb6d7a4277 (patch)
tree9aba2dd7dccee620313dd1a0c3f4f248a70f7a23
parent144fcf754fc2615d1a4643adfce41b89ccf6ba68 (diff)
downloadpostgresql-de323d534c8989bc713c1ac5313024cb6d7a4277.tar.gz
postgresql-de323d534c8989bc713c1ac5313024cb6d7a4277.zip
Require execute permission on the trigger function for CREATE TRIGGER.
This check was overlooked when we added function execute permissions to the system years ago. For an ordinary trigger function it's not a big deal, since trigger functions execute with the permissions of the table owner, so they couldn't do anything the user issuing the CREATE TRIGGER couldn't have done anyway. However, if a trigger function is SECURITY DEFINER, that is not the case. The lack of checking would allow another user to install it on his own table and then invoke it with, essentially, forged input data; which the trigger function is unlikely to realize, so it might do something undesirable, for instance insert false entries in an audit log table. Reported by Dinesh Kumar, patch by Robert Haas Security: CVE-2012-0866
-rw-r--r--doc/src/sgml/ref/create_trigger.sgml3
-rw-r--r--src/backend/commands/trigger.c11
2 files changed, 11 insertions, 3 deletions
diff --git a/doc/src/sgml/ref/create_trigger.sgml b/doc/src/sgml/ref/create_trigger.sgml
index 0fac156feee..b1d8d0046f9 100644
--- a/doc/src/sgml/ref/create_trigger.sgml
+++ b/doc/src/sgml/ref/create_trigger.sgml
@@ -229,7 +229,8 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
<para>
To create a trigger on a table, the user must have the
- <literal>TRIGGER</literal> privilege on the table.
+ <literal>TRIGGER</literal> privilege on the table. The user must
+ also have <literal>EXECUTE</literal> privilege on the trigger function.
</para>
<para>
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index e18fe725ab7..fb3204e873b 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -104,8 +104,8 @@ static void AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
* if TRUE causes us to modify the given trigger name to ensure uniqueness.
*
* When isInternal is not true we require ACL_TRIGGER permissions on the
- * relation. For internal triggers the caller must apply any required
- * permission checks.
+ * relation, as well as ACL_EXECUTE on the trigger function. For internal
+ * triggers the caller must apply any required permission checks.
*
* Note: can return InvalidOid if we decided to not create a trigger at all,
* but a foreign-key constraint. This is a kluge for backwards compatibility.
@@ -309,6 +309,13 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
* Find and validate the trigger function.
*/
funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
+ if (!isInternal)
+ {
+ aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_PROC,
+ NameListToString(stmt->funcname));
+ }
funcrettype = get_func_rettype(funcoid);
if (funcrettype != TRIGGEROID)
{